Terraform module for ecs-deploy

September 23, 2025 ยท View on GitHub

pre-requisites

  • Create a VPC or use the default VPC
  • Create a domain name to be used by the LoadBalancer
  • Issue a certificate using the AWS Certificate Manager (use the same name for the certificate as the cluster_domain property)

Code

module "ecs-deploy" {
  source                   = "github.com/in4it/ecs-deploy//terraform"
  cluster_name             = "mycluster"
  cluster_domain           = "mydomain.com"
  alb_internal             = false
  create_kms_key           = "true" # create a new KMS key instead of using the default ssm key
  vpc_id                   = "vpc-123456"
  vpc_public_subnets       = ["subnet-123456", "subnet-123456"]
  vpc_private_subnets      = ["subnet-123456", "subnet-123456"]
  aws_region               = "us-east-1"
  aws_env                  = "prod"
  instance_type            = "t3.small"
  ssh_key_name             = "${aws_key_pair.mykey.key_name}"
  cluster_minsize          = "1"
  cluster_maxsize          = "1"
  cluster_desired_capacity = "1"
  paramstore_enabled       = "yes"
  ecs_capacity_provider_enabled = true
}

# ssh key
resource "aws_key_pair" "mykey" {
  key_name   = "mykey"
  public_key = "${file("mykey.pub")}"
}

Set keys & passwords

  • The secret keys are not set in terraform (they'd be kept in the state otherwise)
  • You can manually add the secrets or use the commands below to populate the parameter store
aws ssm put-parameter --name '/mycluster-prod/ecs-deploy/JWT_SECRET' --type SecureString --value 'secret' --key-id 'arn:aws:kms:region:0123456789:key/key-id' --region region
aws ssm put-parameter --name '/mycluster-prod/ecs-deploy/DEPLOY_PASSWORD' --type SecureString --value 'secret' --key-id 'arn:aws:kms:region:0123456789:key/key-id' --region region

More Configuration Options

VariableDescription
enable_lb_logsProvide new logs from elb with true value
bucket_lb_logsProvide location of the bucket (.bucket) to the elb logs if enable_lb_logs is true
ecs_init_scriptProvide new (local) path to the ecs init script
ecs_ecs2_extra_sgProvide extra security group for EC2 instance
ecs_ecs2_vpc_cidr_sgProvide change egress CIDR in the cluster sg for EC2 instance
sns_endpointOverride sns endpoint domain
ecs_capacity_provider_enabledEnable AWS ECS capacity provider
capacity_maximum_scaling_step_sizeCapacity provider maximum scaling step
capacity_minimum_scaling_step_sizeCapacity provider minimum scaling step
target_capacityTarget capacity

Capacity provider migrations notes:

Before applying ecs-deploy module with ecs_capacity_provider_enabled set to true, make sure that all instances in AWS ASG have scale in protection enabled, otherwise it will result in an error:

Error: error creating capacity provider: ClientException: The managed termination protection setting for the capacity provider is invalid. To enable managed termination protection for a capacity provider, the Auto Scaling group must have instance protection from scale in enabled.

Requirements

NameVersion
terraform>= 0.12

Providers

NameVersion
awsn/a

Modules

No modules.

Resources

NameType
aws_alb.albresource
aws_alb_listener.alb-httpresource
aws_alb_listener.alb-httpsresource
aws_alb_listener_rule.ecs-deployresource
aws_alb_target_group.ecs-deployresource
aws_appmesh_virtual_node.ecs-deployresource
aws_appmesh_virtual_service.ecs-deployresource
aws_autoscaling_group.clusterresource
aws_autoscaling_lifecycle_hook.clusterresource
aws_cloudwatch_event_rule.ecs-deployresource
aws_cloudwatch_event_rule.ecs-deploy-autoscalingresource
aws_cloudwatch_event_target.ecs-deployresource
aws_cloudwatch_event_target.ecs-deploy-autoscalingresource
aws_cloudwatch_log_group.clusterresource
aws_cloudwatch_log_group.ecs-deployresource
aws_dynamodb_table.ecs-deployresource
aws_ecs_capacity_provider.deployresource
aws_ecs_cluster.clusterresource
aws_ecs_cluster_capacity_providers.clusterresource
aws_ecs_service.ecs-deployresource
aws_ecs_task_definition.ecs-deployresource
aws_ecs_task_definition.ecs-deploy-appmeshresource
aws_iam_instance_profile.cluster-ec2-roleresource
aws_iam_role.cluster-ec2-roleresource
aws_iam_role.cluster-service-roleresource
aws_iam_role.ecs-deployresource
aws_iam_role.ecs-task-execution-roleresource
aws_iam_role_policy.cluster-ec2-roleresource
aws_iam_role_policy.cluster-service-roleresource
aws_iam_role_policy.ecs-deploy-policyresource
aws_iam_role_policy.ecs-task-execution-roleresource
aws_kms_alias.ssmresource
aws_kms_key.ssmresource
aws_launch_template.clusterresource
aws_lb_listener_certificate.extra-certificatesresource
aws_security_group.albresource
aws_security_group.clusterresource
aws_security_group.ecs-deploy-awsvpcresource
aws_service_discovery_service.ecs-deployresource
aws_sns_topic.ecs-deployresource
aws_sns_topic_subscription.ecs-deployresource
aws_ssm_parameter.ecs-deploy-autoscaling-down-cooldownresource
aws_ssm_parameter.ecs-deploy-autoscaling-down-intervalresource
aws_ssm_parameter.ecs-deploy-autoscaling-down-periodresource
aws_ssm_parameter.ecs-deploy-autoscaling-strategiesresource
aws_ssm_parameter.ecs-deploy-autoscaling-up-cooldownresource
aws_ssm_parameter.ecs-deploy-autoscaling-up-intervalresource
aws_ssm_parameter.ecs-deploy-autoscaling-up-periodresource
aws_ssm_parameter.ecs-deploy-aws-account-envresource
aws_ssm_parameter.ecs-deploy-dynamodbresource
aws_ssm_parameter.ecs-deploy-kms-idresource
aws_ssm_parameter.ecs-deploy-loadbalancer-domainresource
aws_ssm_parameter.ecs-deploy-paramstore-auto-injectresource
aws_ssm_parameter.ecs-deploy-paramstore-cloudwatchresource
aws_ssm_parameter.ecs-deploy-paramstore-cloudwatch-prefixresource
aws_ssm_parameter.ecs-deploy-paramstore-deploy-max-waitresource
aws_ssm_parameter.ecs-deploy-paramstore-ecs-ecr-scan-on-pushresource
aws_ssm_parameter.ecs-deploy-paramstore-ip-whitelistresource
aws_ssm_parameter.ecs-deploy-paramstore-prefixresource
aws_ssm_parameter.ecs-deploy-saml-acs-urlresource
aws_ssm_parameter.ecs-deploy-saml-enabledresource
aws_ssm_parameter.ecs-deploy-saml-metadata-urlresource
aws_ssm_parameter.ecs-deploy-service-roleresource
aws_ssm_parameter.ecs-deploy-url-prefixresource
aws_ssm_parameter.ecs-paramstore-assume-roleresource
aws_acm_certificate.certificatedata source
aws_acm_certificate.extra-certificatesdata source
aws_ami.ecsdata source
aws_caller_identity.currentdata source
aws_kms_key.ssmdata source

Inputs

NameDescriptionTypeDefaultRequired
alb_internaltrue if ALB needs to be internalstring"false"no
autoscaling_down_cooldownautoscaling variablesstring""no
autoscaling_down_intervaln/astring""no
autoscaling_down_periodn/astring""no
autoscaling_strategiesenable/disable autoscaling strategiesstring""no
autoscaling_up_cooldownn/astring""no
autoscaling_up_intervaln/astring""no
autoscaling_up_periodn/astring""no
aws_envenvironment to useanyn/ayes
aws_regionThe AWS region to create things in.anyn/ayes
bucket_lb_logsName bucket located alb logs if logs is truestring""no
capacity_maximum_scaling_step_sizen/anumber1000no
capacity_minimum_scaling_step_sizen/anumber1no
cloudwatch_log_group_kms_arncloudwatch log group kms arnstring""no
cloudwatch_log_retention_periodcloudwatch retention period in daysstring"0"no
cluster_desired_capacitydesired capacity of clusteranyn/ayes
cluster_domainDomain to use for ALBanyn/ayes
cluster_maxsizemaximum size of clusteranyn/ayes
cluster_minsizeminimum size of clusteranyn/ayes
cluster_nameCluster namestring"services"no
cluster_termination_policiesTermination policies of clusterlist
[
"OldestLaunchTemplate",
"OldestInstance"
]
no
cpu_creditsCPU credits type for launch templatestring"standard"no
create_kms_keyCreate a KMS key for ssm or use default ssm keyanyn/ayes
drop_invalid_header_fieldstrue if needs to drop invalid header fieldsstring"false"no
dynamodb_pitr_recovery_periodnumber of days to retain recovery points fornumber35no
dynamodb_read_capacityn/anumber2no
dynamodb_write_capacityn/anumber2no
ecs_capacity_provider_enabledn/aboolfalseno
ecs_deploy_appmesh_nameappmesh namestring""no
ecs_deploy_appmesh_releaseappmesh release versionstring"v1.11.1.1-prod"no
ecs_deploy_awsvpcenable awsvpc for the ecs-deploy ecs serviceboolfalseno
ecs_deploy_awsvpc_allowsgallow extra sgs when using awsvpcstring""no
ecs_deploy_cpun/anumber128no
ecs_deploy_debugecs deploy debugstring"false"no
ecs_deploy_enable_appmeshenable appmeshboolfalseno
ecs_deploy_imageimage location of ecs-deploystring"709825985650.dkr.ecr.us-east-1.amazonaws.com/in4it/ecs-deploy"no
ecs_deploy_max_wait_secondsn/anumber900no
ecs_deploy_memory_reservationn/anumber64no
ecs_deploy_service_discovery_domainservice discovery domainstring""no
ecs_deploy_service_discovery_idjoin a service discovery domain providing the idstring""no
ecs_deploy_versionecs deploy versionstring"v1.0.43"no
ecs_ec2_extra_sgn/astring""no
ecs_ec2_vpc_cidr_sgn/astring"0.0.0.0/0"no
ecs_ecr_scan_on_pushn/astring"false"no
ecs_init_scriptn/astring""no
ecs_whitelistn/astring"0.0.0.0/0"no
enable_dynamodb_encryptionDynamoDB variablesboolfalseno
enable_dynamodb_pitrenable point in time recoveryboolfalseno
enable_lb_logstrue if needs logs for ALBstring"false"no
extra_domainsextra domain that need to be supported by the ALBlist[]no
fixed_response_bodyfixed response bodystring"No service configured at this address"no
fixed_response_codefixed response http codestring"404"no
fixed_response_content_typefixed response content typestring"text/plain"no
instance_typeinstance typeanyn/ayes
metadata_options_http_tokensmetadata options IMDSv1 or IMDSv2string"required"no
paramstore_assume_roleassume role when using paramstorestring""no
paramstore_enabledEnable parameter storeanyn/ayes
paramstore_injectn/astring"no"no
prod_coden/astring"3x0v7m3npdgzaiw2f8lwsgju5"no
saml_acs_urlsaml acs url, if the default acs url needs to be overwrittenstring""no
saml_enabledEnable SAML authstring"no"no
saml_metadata_urlSAML metadata urlstring"https://identityprovider/metadata.xml"no
sns_endpointsns variablesstring""no
sns_kms_master_key_idKMS key arn to encrypt SNS topicstring""no
ssh_key_namessh key nameanyn/ayes
ssl_policyTLS policy for https listenerstring"ELBSecurityPolicy-TLS13-1-2-2021-06"no
target_capacityn/anumber100no
url_prefixURL prefixstring"/ecs-deploy"no
volume_typevolume typestring"gp2"no
vpc_idVPC IDanyn/ayes
vpc_private_subnetsVPC private subnetslist(string)n/ayes
vpc_public_subnetsVPC public subnetslist(string)n/ayes
yum_proxy_urlyum http proxy urlstring""no

Outputs

NameDescription
alb-dns-namen/a
alb-sgn/a
alb-zone-idn/a
cluster-cloudwatch-log-group-namen/a
cluster-ec2-role-arnn/a
cluster-ec2-role-namen/a
ecs-deploy-cloudwatch-log-group-namen/a
paramstore-kms-arnn/a
sg-clustern/a