From 7a41657bd07d42b73757863266b6ea68710c36ce Mon Sep 17 00:00:00 2001 From: Bryant Biggs Date: Wed, 8 Jun 2022 09:25:50 -0400 Subject: [PATCH] feat!: Upgrade module to include capacity providers and bump minimum supported versions (#60) --- .pre-commit-config.yaml | 4 +- README.md | 211 +++++++++++++++--- UPGRADE-4.0.md | 207 +++++++++++++++++ examples/complete-ecs/README.md | 81 ------- examples/complete-ecs/main.tf | 146 ------------ .../service-hello-world/versions.tf | 7 - examples/complete-ecs/templates/user-data.sh | 10 - examples/complete/README.md | 65 ++++++ examples/complete/main.tf | 191 ++++++++++++++++ examples/complete/outputs.tf | 31 +++ .../service-hello-world/main.tf | 14 +- .../service-hello-world}/outputs.tf | 0 .../service-hello-world/variables.tf | 0 .../service-hello-world}/versions.tf | 4 +- .../{complete-ecs => complete}/variables.tf | 0 .../complete}/versions.tf | 4 +- examples/fargate/README.md | 58 +++++ examples/fargate/main.tf | 70 ++++++ examples/fargate/outputs.tf | 31 +++ .../outputs.tf => fargate/variables.tf} | 0 examples/fargate/versions.tf | 10 + main.tf | 105 ++++++++- modules/ecs-instance-profile/README.md | 53 ----- modules/ecs-instance-profile/main.tf | 47 ---- modules/ecs-instance-profile/outputs.tf | 14 -- modules/ecs-instance-profile/variables.tf | 16 -- modules/service/README.md | 66 ++++++ modules/service/main.tf | 1 + modules/service/outputs.tf | 0 modules/service/variables.tf | 0 modules/service/versions.tf | 10 + outputs.tf | 37 ++- variables.tf | 57 +++-- versions.tf | 4 +- 34 files changed, 1092 insertions(+), 462 deletions(-) create mode 100644 UPGRADE-4.0.md delete mode 100644 examples/complete-ecs/README.md delete mode 100644 examples/complete-ecs/main.tf delete mode 100644 examples/complete-ecs/service-hello-world/versions.tf delete mode 100644 examples/complete-ecs/templates/user-data.sh create mode 100644 examples/complete/README.md create mode 100644 examples/complete/main.tf create mode 100644 examples/complete/outputs.tf rename examples/{complete-ecs => complete}/service-hello-world/main.tf (60%) rename examples/{complete-ecs => complete/service-hello-world}/outputs.tf (100%) rename examples/{complete-ecs => complete}/service-hello-world/variables.tf (100%) rename examples/{complete-ecs => complete/service-hello-world}/versions.tf (60%) rename examples/{complete-ecs => complete}/variables.tf (100%) rename {modules/ecs-instance-profile => examples/complete}/versions.tf (60%) create mode 100644 examples/fargate/README.md create mode 100644 examples/fargate/main.tf create mode 100644 examples/fargate/outputs.tf rename examples/{complete-ecs/service-hello-world/outputs.tf => fargate/variables.tf} (100%) create mode 100644 examples/fargate/versions.tf delete mode 100644 modules/ecs-instance-profile/README.md delete mode 100644 modules/ecs-instance-profile/main.tf delete mode 100644 modules/ecs-instance-profile/outputs.tf delete mode 100644 modules/ecs-instance-profile/variables.tf create mode 100644 modules/service/README.md create mode 100644 modules/service/main.tf create mode 100644 modules/service/outputs.tf create mode 100644 modules/service/variables.tf create mode 100644 modules/service/versions.tf diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 093121e..b3ff80e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.62.3 + rev: v1.72.1 hooks: - id: terraform_fmt - id: terraform_validate @@ -23,7 +23,7 @@ repos: - '--args=--only=terraform_standard_module_structure' - '--args=--only=terraform_workspace_remote' - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.2.0 hooks: - id: check-merge-conflict - id: end-of-file-fixer diff --git a/README.md b/README.md index 24a9a70..8bc914b 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,214 @@ -# AWS Elastic Container Service (ECS) Terraform module +# AWS ECS Terraform module -Terraform module which creates ECS resources on AWS. +Terraform module which creates ECS (Elastic Container Service) resources on AWS. -This module focuses purely on ECS and nothing else. Therefore only these resources can be created with this module: +## Available Features -- [ECS](https://www.terraform.io/docs/providers/aws/r/ecs_cluster.html) -- [IAM](https://www.terraform.io/docs/providers/aws/r/iam_instance_profile.html) - -However, having said the above to have a proper ECS cluster up and running multiple resources are needed. In most cases creating these resources is heavily opinionated and or context-bound. That is why this module does not create these resources. But you still need them to have a production ready environment. Therefore the example area shows how to create everything needed for a production environment. +- ECS cluster +- Fargate capacity providers +- EC2 AutoScaling Group capacity providers ## Usage +### Fargate Capacity Providers + +```hcl +module "ecs" { + source = "terraform-aws-modules/ecs/aws" + + name = "ecs-fargate" + + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + cloud_watch_log_group_name = "/aws/ecs/aws-ec2" + } + } + } + + fargate_capacity_providers = { + FARGATE = { + default_capacity_provider_strategy = { + weight = 50 + } + } + FARGATE_SPOT = { + default_capacity_provider_strategy = { + weight = 50 + } + } + } + + tags = { + Environment = "Development" + Project = "EcsEc2" + } +} +``` + +### EC2 Autoscaling Capacity Providers + +```hcl +module "ecs" { + source = "terraform-aws-modules/ecs/aws" + + name = "ecs-ec2" + + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + cloud_watch_log_group_name = "/aws/ecs/aws-ec2" + } + } + } + + autoscaling_capacity_providers = { + one = { + auto_scaling_group_arn = "arn:aws:autoscaling:eu-west-1:012345678901:autoScalingGroup:08419a61:autoScalingGroupName/ecs-ec2-one-20220603194933774300000011" + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 5 + minimum_scaling_step_size = 1 + status = "ENABLED" + target_capacity = 60 + } + + default_capacity_provider_strategy = { + weight = 60 + base = 20 + } + } + two = { + auto_scaling_group_arn = "arn:aws:autoscaling:eu-west-1:012345678901:autoScalingGroup:08419a61:autoScalingGroupName/ecs-ec2-two-20220603194933774300000022" + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 15 + minimum_scaling_step_size = 5 + status = "ENABLED" + target_capacity = 90 + } + + default_capacity_provider_strategy = { + weight = 40 + } + } + } + + tags = { + Environment = "Development" + Project = "EcsEc2" + } +} +``` + +### Fargate & EC2 Autoscaling Capacity Providers + ```hcl module "ecs" { source = "terraform-aws-modules/ecs/aws" - name = "my-ecs" + name = "ecs-mixed" - container_insights = true + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + cloud_watch_log_group_name = "/aws/ecs/aws-ec2" + } + } + } - capacity_providers = ["FARGATE", "FARGATE_SPOT"] + fargate_capacity_providers = { + FARGATE = { + default_capacity_provider_strategy = { + weight = 50 + } + } + FARGATE_SPOT = { + default_capacity_provider_strategy = { + weight = 50 + } + } + } - default_capacity_provider_strategy = [ - { - capacity_provider = "FARGATE_SPOT" + autoscaling_capacity_providers = { + one = { + auto_scaling_group_arn = "arn:aws:autoscaling:eu-west-1:012345678901:autoScalingGroup:08419a61:autoScalingGroupName/ecs-ec2-one-20220603194933774300000011" + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 5 + minimum_scaling_step_size = 1 + status = "ENABLED" + target_capacity = 60 + } + + default_capacity_provider_strategy = { + weight = 60 + base = 20 + } } - ] + two = { + auto_scaling_group_arn = "arn:aws:autoscaling:eu-west-1:012345678901:autoScalingGroup:08419a61:autoScalingGroupName/ecs-ec2-two-20220603194933774300000022" + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 15 + minimum_scaling_step_size = 5 + status = "ENABLED" + target_capacity = 90 + } + + default_capacity_provider_strategy = { + weight = 40 + } + } + } tags = { Environment = "Development" + Project = "EcsEc2" } } ``` -## Conditional creation +## Conditional Creation -Sometimes you need to have a way to create ECS resources conditionally but Terraform does not allow to use `count` inside `module` block, so the solution is to specify argument `create_ecs`. +The following values are provided to toggle on/off creation of the associated resources as desired: ```hcl -# ECS cluster will not be created module "ecs" { source = "terraform-aws-modules/ecs/aws" - version = "~> 2.0" - create_ecs = false + # Disable creation of cluster and all resources + create = false + # ... omitted } ``` ## Examples -- [Complete ECS](https://github.com/terraform-aws-modules/terraform-aws-ecs/tree/master/examples/complete-ecs) +- [ECS Cluster w/ EC2 Autoscaling Capacity Provider](https://github.com/terraform-aws-modules/terraform-aws-ecs/tree/master/examples/complete) +- [ECS Cluster w/ Fargate Capacity Provider](https://github.com/terraform-aws-modules/terraform-aws-ecs/tree/master/examples/fargate) ## Requirements | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 3.74 | +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.6 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.74 | +| [aws](#provider\_aws) | >= 4.6 | ## Modules @@ -74,6 +218,7 @@ No modules. | Name | Type | |------|------| +| [aws_ecs_capacity_provider.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_capacity_provider) | resource | | [aws_ecs_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster) | resource | | [aws_ecs_cluster_capacity_providers.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster_capacity_providers) | resource | @@ -81,20 +226,22 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [capacity\_providers](#input\_capacity\_providers) | List of short names of one or more capacity providers to associate with the cluster. Valid values also include FARGATE and FARGATE\_SPOT. | `list(string)` | `[]` | no | -| [container\_insights](#input\_container\_insights) | Controls if ECS Cluster has container insights enabled | `bool` | `false` | no | -| [create\_ecs](#input\_create\_ecs) | Controls if ECS should be created | `bool` | `true` | no | -| [default\_capacity\_provider\_strategy](#input\_default\_capacity\_provider\_strategy) | The capacity provider strategy to use by default for the cluster. Can be one or more. | `list(map(any))` | `[]` | no | -| [name](#input\_name) | Name to be used on all the resources as identifier, also the name of the ECS cluster | `string` | `null` | no | -| [tags](#input\_tags) | A map of tags to add to ECS Cluster | `map(string)` | `{}` | no | +| [autoscaling\_capacity\_providers](#input\_autoscaling\_capacity\_providers) | Map of autoscaling capacity provider definitons to create for the cluster | `any` | `{}` | no | +| [cluster\_configuration](#input\_cluster\_configuration) | The execute command configuration for the cluster | `any` | `{}` | no | +| [cluster\_name](#input\_cluster\_name) | Name of the cluster (up to 255 letters, numbers, hyphens, and underscores) | `string` | `""` | no | +| [cluster\_settings](#input\_cluster\_settings) | Configuration block(s) with cluster settings. For example, this can be used to enable CloudWatch Container Insights for a cluster | `map(string)` |
{
"name": "containerInsights",
"value": "enabled"
}
| no | +| [create](#input\_create) | Determines whether resources will be created (affects all resources) | `bool` | `true` | no | +| [fargate\_capacity\_providers](#input\_fargate\_capacity\_providers) | Map of Fargate capacity provider definitions to use for the cluster | `any` | `{}` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | ## Outputs | Name | Description | |------|-------------| -| [ecs\_cluster\_arn](#output\_ecs\_cluster\_arn) | ARN of the ECS Cluster | -| [ecs\_cluster\_id](#output\_ecs\_cluster\_id) | ID of the ECS Cluster | -| [ecs\_cluster\_name](#output\_ecs\_cluster\_name) | The name of the ECS cluster | +| [autoscaling\_capacity\_providers](#output\_autoscaling\_capacity\_providers) | Map of autoscaling capacity providers created and their attributes | +| [cluster\_arn](#output\_cluster\_arn) | ARN that identifies the cluster | +| [cluster\_capacity\_providers](#output\_cluster\_capacity\_providers) | Map of cluster capacity providers attributes | +| [cluster\_id](#output\_cluster\_id) | ID that identifies the cluster | ## Authors diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md new file mode 100644 index 0000000..a1bf05d --- /dev/null +++ b/UPGRADE-4.0.md @@ -0,0 +1,207 @@ +# Upgrade from v3.x to v4.x + +Please consult the `examples` directory for reference example configurations. If you find a bug, please open an issue with supporting configuration to reproduce. + +## List of backwards incompatible changes + +- Minimum supported version of Terraform AWS provider updated to v4.6 to support the latest resources utilized +- Minimum supported version of Terraform updated to v1.0 +- `ecs-instance-profile` sub-module has been removed; this functionality is available through the [`terraform-aws-modules/terraform-aws-autoscaling`](https://github.com/terraform-aws-modules/terraform-aws-autoscaling) module starting with version [v6.5.0](https://github.com/terraform-aws-modules/terraform-aws-autoscaling/pull/194). Please see the [`examples/complete`](https://github.com/terraform-aws-modules/terraform-aws-ecs/tree/master/examples/complete) example for a demonstration on how to use and integrate with the `terraform-aws-autoscaling` module. +- The `container_insights` and `capacity_providers` variables have been replaced by new variables - see below for more details + +## Additional changes + +### Added + +- Support for `aws_ecs_capacity_provider` has been added to the module + +### Modified + +- The `container_insights` variable has been replaced with the `cluster_settings` variable which allows users to enable/disable container insights and also allows for not specifying at all for regions where container insights is currently not supported. +- The `capacity_providers` variable has been replaced with `fargate_capacity_providers`and `autoscaling_capacity_providers`. This allows users to specify either Fargate based capacity providers, EC2 AutoScaling Group capacity providers, or both. +- Previously `capacity_providers` and `default_capacity_provider_strategy` usage looked like: +```hcl + capacity_providers = ["FARGATE", "FARGATE_SPOT"] + + default_capacity_provider_strategy = [{ + capacity_provider = "FARGATE" + weight = 50 + base = 20 + }, { + capacity_provider = "FARGATE_SPOT" + weight = 50 + }] +``` +Where the current equivalent now looks like: +```hcl + fargate_capacity_providers = { + FARGATE = { + default_capacity_provider_strategy = { + weight = 50 + base = 20 + } + } + FARGATE_SPOT = { + default_capacity_provider_strategy = { + weight = 50 + } + } + } +``` +- Previously `capacity_providers` accepted the name of an AutoScaling Group created externally; this is now replaced by the usage of `autoscaling_capacity_providers` which incorporates the usage of the newly added support for `aws_ecs_capacity_provider` + +### Removed + +- `ecs-instance-profile` sub-module has been removed; this functionality is available through the [`terraform-aws-modules/terraform-aws-autoscaling`](https://github.com/terraform-aws-modules/terraform-aws-autoscaling) module starting with version [v6.5.0](https://github.com/terraform-aws-modules/terraform-aws-autoscaling/pull/194). Please see the [`examples/complete`](https://github.com/terraform-aws-modules/terraform-aws-ecs/tree/master/examples/complete) example for a demonstration on how to use and integrate with the `terraform-aws-autoscaling` module. + +### Variable and output changes + +1. Removed variables: + + - `default_capacity_provider_strategy` is now incorporated into the `fargate_capacity_providers` and `autoscaling_capacity_providers` variables. + +2. Renamed variables: + + - `create_ecs` -> `create` + - `name` -> `cluster_name` + +3. Added variables: + + - `cluster_configuration` has been added under a dynamic block with all current attributes supported + +4. Removed outputs: + + - `ecs_cluster_name` + +5. Renamed outputs: + + - `ecs_cluster_id` -> `cluster_id` + - `ecs_cluster_arn` -> `cluster_arn` + +6. Added outputs: + + - `cluster_capacity_providers` + - `autoscaling_capacity_providers` + +## Upgrade Migrations + +### Before v3.x Example + +```hcl +module "ecs" { + source = "terraform-aws-modules/ecs/aws" + version = "3.5.0" + + name = "example" + container_insights = true + + capacity_providers = ["FARGATE", "FARGATE_SPOT", aws_ecs_capacity_provider.prov1.name] + + default_capacity_provider_strategy = [{ + capacity_provider = aws_ecs_capacity_provider.prov1.name + weight = "1" + }] +} + +module "ec2_profile" { + source = "terraform-aws-modules/ecs/aws//modules/ecs-instance-profile" + version = "3.5.0" + + name = local.name +} + +resource "aws_ecs_capacity_provider" "prov1" { + name = "prov1" + + auto_scaling_group_provider { + auto_scaling_group_arn = module.autoscaling.autoscaling_group_arn + } +} +``` + +### After v4.x Example + +```hcl +module "ecs" { + source = "terraform-aws-modules/ecs/aws" + version = "4.0.0" + + cluster_name = "example" + + fargate_capacity_providers = { + FARGATE = {} + FARGATE_SPOT = {} + } + + autoscaling_capacity_providers = { + prov1 = { + auto_scaling_group_arn = module.autoscaling.autoscaling_group_arn + default_capacity_provider_strategy = { + weight = 1 + } + } + } +} + +module "ec2_profile" { + source = "terraform-aws-modules/ecs/aws//modules/ecs-instance-profile" + # Users can pin and stay on v3.5.0 until they able to use the IAM instance + # profile provided through the autoscaling group module + version = "3.5.0" + + name = "example +} +``` + +### Diff of Before vs After + +```diff +- resource "aws_ecs_capacity_provider" "prov1" { +- name = "prov1" +- +- auto_scaling_group_provider { +- auto_scaling_group_arn = module.autoscaling.autoscaling_group_arn +- } +- } + + module "ecs" { + source = "terraform-aws-modules/ecs/aws" +- version = "3.5.0" ++ version = "4.0.0" + +- name = "example" ++ cluster_name = "example" + +- container_insights = true ++ # On by default now + +- capacity_providers = ["FARGATE", "FARGATE_SPOT", aws_ecs_capacity_provider.prov1.name] +- default_capacity_provider_strategy = [{ +- capacity_provider = aws_ecs_capacity_provider.prov1.name +- weight = "1" +- }] + ++ fargate_capacity_providers = { ++ FARGATE = {} ++ FARGATE_SPOT = {} ++ } + ++ autoscaling_capacity_providers = { ++ prov1 = { ++ auto_scaling_group_arn = module.autoscaling.autoscaling_group_arn ++ default_capacity_provider_strategy = { ++ weight = 1 ++ } ++ } ++ } +} +``` + +### State Move Commands + +In conjunction with the changes above, users can elect to move their external capacity provider(s) under this module using the following move command. Command is shown using the values from the example shown above, please update to suit your configuration names: + +```sh +# Cluster +terraform state mv 'aws_ecs_capacity_provider.prov1' 'module.ecs.aws_ecs_capacity_provider.this["prov1"]' +``` diff --git a/examples/complete-ecs/README.md b/examples/complete-ecs/README.md deleted file mode 100644 index f17a3f4..0000000 --- a/examples/complete-ecs/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Complete ECS - -This example uses only verified Terraform modules to create all resources that are needed for an ECS cluster that is sufficient for staging or production environment. - -While this example is still in the early stage there are other repositories that show how to create an ECS cluster: - -* -* -* -* - -## TODO - -Things still needed in the example: - -* AWS network infrastructure on what is created -* Full explanation on why certain resources are created -* Create EC2 instance specific SecurityGroup instead of using the default one from VPC module -* Push logs of default EC2 stuff (docker, ecs agent, etc...) to CloudWatch logs -* Add an example with ALB -* Add an example with NLB -* Add an example with ELB -* Create a Fargate example - -## Usage - -To run this example you need to execute: - -```bash -terraform init -terraform plan -terraform apply -``` - -Note that this example may create resources which can cost money (AWS EC2 instances, for example). Run `terraform destroy` when you don't need these resources. - -## Explanation - -Current version creates an high-available VPC with instances that are attached to ECS. ECS tasks can be run on these instances but they are not exposed to anything. - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 3.74 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 3.74 | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [asg](#module\_asg) | terraform-aws-modules/autoscaling/aws | ~> 4.0 | -| [disabled\_ecs](#module\_disabled\_ecs) | ../../ | n/a | -| [ec2\_profile](#module\_ec2\_profile) | ../../modules/ecs-instance-profile | n/a | -| [ecs](#module\_ecs) | ../../ | n/a | -| [hello\_world](#module\_hello\_world) | ./service-hello-world | n/a | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | - -## Resources - -| Name | Type | -|------|------| -| [aws_ecs_capacity_provider.prov1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_capacity_provider) | resource | -| [aws_ami.amazon_linux_ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | -| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | - -## Inputs - -No inputs. - -## Outputs - -No outputs. - diff --git a/examples/complete-ecs/main.tf b/examples/complete-ecs/main.tf deleted file mode 100644 index eb6aa37..0000000 --- a/examples/complete-ecs/main.tf +++ /dev/null @@ -1,146 +0,0 @@ -locals { - name = "complete-ecs" - environment = "dev" - - # This is the convention we use to know what belongs to each other - ec2_resources_name = "${local.name}-${local.environment}" -} - -data "aws_availability_zones" "available" { - state = "available" -} - -module "vpc" { - source = "terraform-aws-modules/vpc/aws" - version = "~> 3.0" - - name = local.name - - cidr = "10.1.0.0/16" - - azs = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1]] - private_subnets = ["10.1.1.0/24", "10.1.2.0/24"] - public_subnets = ["10.1.11.0/24", "10.1.12.0/24"] - - enable_nat_gateway = false # false is just faster - - tags = { - Environment = local.environment - Name = local.name - } -} - -#----- ECS -------- -module "ecs" { - source = "../../" - - name = local.name - container_insights = true - - capacity_providers = ["FARGATE", "FARGATE_SPOT", aws_ecs_capacity_provider.prov1.name] - - default_capacity_provider_strategy = [{ - capacity_provider = aws_ecs_capacity_provider.prov1.name # "FARGATE_SPOT" - weight = "1" - }] - - tags = { - Environment = local.environment - } -} - -module "ec2_profile" { - source = "../../modules/ecs-instance-profile" - - name = local.name - - tags = { - Environment = local.environment - } -} - -resource "aws_ecs_capacity_provider" "prov1" { - name = "prov1" - - auto_scaling_group_provider { - auto_scaling_group_arn = module.asg.autoscaling_group_arn - } - -} - -#----- ECS Services-------- -module "hello_world" { - source = "./service-hello-world" - - cluster_id = module.ecs.ecs_cluster_id -} - -#----- ECS Resources-------- - -#For now we only use the AWS ECS optimized ami -data "aws_ami" "amazon_linux_ecs" { - most_recent = true - - owners = ["amazon"] - - filter { - name = "name" - values = ["amzn-ami-*-amazon-ecs-optimized"] - } - - filter { - name = "owner-alias" - values = ["amazon"] - } -} - -module "asg" { - source = "terraform-aws-modules/autoscaling/aws" - version = "~> 4.0" - - name = local.ec2_resources_name - - # Launch configuration - lc_name = local.ec2_resources_name - use_lc = true - create_lc = true - - image_id = data.aws_ami.amazon_linux_ecs.id - instance_type = "t2.micro" - security_groups = [module.vpc.default_security_group_id] - iam_instance_profile_name = module.ec2_profile.iam_instance_profile_id - user_data = templatefile("${path.module}/templates/user-data.sh", { - cluster_name = local.name - }) - - # Auto scaling group - vpc_zone_identifier = module.vpc.private_subnets - health_check_type = "EC2" - min_size = 0 - max_size = 2 - desired_capacity = 0 # we don't need them for the example - wait_for_capacity_timeout = 0 - - tags = [ - { - key = "Environment" - value = local.environment - propagate_at_launch = true - }, - { - key = "Cluster" - value = local.name - propagate_at_launch = true - }, - ] -} - -################### -# Disabled cluster -################### - -module "disabled_ecs" { - source = "../../" - - create_ecs = false -} diff --git a/examples/complete-ecs/service-hello-world/versions.tf b/examples/complete-ecs/service-hello-world/versions.tf deleted file mode 100644 index 5641dfb..0000000 --- a/examples/complete-ecs/service-hello-world/versions.tf +++ /dev/null @@ -1,7 +0,0 @@ -terraform { - required_version = ">= 0.12.6" - - required_providers { - aws = ">= 2.0" - } -} diff --git a/examples/complete-ecs/templates/user-data.sh b/examples/complete-ecs/templates/user-data.sh deleted file mode 100644 index ec4e61c..0000000 --- a/examples/complete-ecs/templates/user-data.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# ECS config -{ - echo "ECS_CLUSTER=${cluster_name}" -} >> /etc/ecs/ecs.config - -start ecs - -echo "Done" diff --git a/examples/complete/README.md b/examples/complete/README.md new file mode 100644 index 0000000..15052e6 --- /dev/null +++ b/examples/complete/README.md @@ -0,0 +1,65 @@ +# ECS Cluster w/ EC2 Autoscaling + +Configuration in this directory creates: + +- ECS cluster using autoscaling group capacity provider +- Autoscaling groups with IAM instance profile to be used by ECS cluster +- Example ECS service + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.6 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.6 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [autoscaling](#module\_autoscaling) | terraform-aws-modules/autoscaling/aws | ~> 6.5 | +| [autoscaling\_sg](#module\_autoscaling\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 | +| [ecs](#module\_ecs) | ../.. | n/a | +| [ecs\_disabled](#module\_ecs\_disabled) | ../.. | n/a | +| [hello\_world](#module\_hello\_world) | ./service-hello-world | n/a | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_ssm_parameter.ecs_optimized_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [autoscaling\_capacity\_providers](#output\_autoscaling\_capacity\_providers) | Map of capacity providers created and their attributes | +| [cluster\_arn](#output\_cluster\_arn) | ARN that identifies the cluster | +| [cluster\_capacity\_providers](#output\_cluster\_capacity\_providers) | Map of cluster capacity providers attributes | +| [cluster\_id](#output\_cluster\_id) | ID that identifies the cluster | + diff --git a/examples/complete/main.tf b/examples/complete/main.tf new file mode 100644 index 0000000..d589b07 --- /dev/null +++ b/examples/complete/main.tf @@ -0,0 +1,191 @@ +provider "aws" { + region = local.region +} + +locals { + region = "eu-west-1" + name = "ecs-ex-${replace(basename(path.cwd), "_", "-")}" + + user_data = <<-EOT + #!/bin/bash + cat <<'EOF' >> /etc/ecs/ecs.config + ECS_CLUSTER=${local.name} + ECS_LOGLEVEL=debug + EOF + EOT + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-ecs" + } +} + +################################################################################ +# ECS Module +################################################################################ + +module "ecs" { + source = "../.." + + cluster_name = local.name + + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + # You can set a simple string and ECS will create the CloudWatch log group for you + # or you can create the resource yourself as shown here to better manage retetion, tagging, etc. + # Embedding it into the module is not trivial and therefore it is externalized + cloud_watch_log_group_name = aws_cloudwatch_log_group.this.name + } + } + } + + # Capacity provider - autoscaling groups + autoscaling_capacity_providers = { + one = { + auto_scaling_group_arn = module.autoscaling["one"].autoscaling_group_arn + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 5 + minimum_scaling_step_size = 1 + status = "ENABLED" + target_capacity = 60 + } + + default_capacity_provider_strategy = { + weight = 60 + base = 20 + } + } + two = { + auto_scaling_group_arn = module.autoscaling["two"].autoscaling_group_arn + managed_termination_protection = "ENABLED" + + managed_scaling = { + maximum_scaling_step_size = 15 + minimum_scaling_step_size = 5 + status = "ENABLED" + target_capacity = 90 + } + + default_capacity_provider_strategy = { + weight = 40 + } + } + } + + tags = local.tags +} + +module "hello_world" { + source = "./service-hello-world" + + cluster_id = module.ecs.cluster_id +} + +module "ecs_disabled" { + source = "../.." + + create = false +} + +################################################################################ +# Supporting Resources +################################################################################ + +# https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html#ecs-optimized-ami-linux +data "aws_ssm_parameter" "ecs_optimized_ami" { + name = "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended" +} + +module "autoscaling" { + source = "terraform-aws-modules/autoscaling/aws" + version = "~> 6.5" + + for_each = { + one = { + instance_type = "t3.micro" + } + two = { + instance_type = "t3.small" + } + } + + name = "${local.name}-${each.key}" + + image_id = jsondecode(data.aws_ssm_parameter.ecs_optimized_ami.value)["image_id"] + instance_type = each.value.instance_type + + security_groups = [module.autoscaling_sg.security_group_id] + user_data = base64encode(local.user_data) + ignore_desired_capacity_changes = true + + create_iam_instance_profile = true + iam_role_name = local.name + iam_role_description = "ECS role for ${local.name}" + iam_role_policies = { + AmazonEC2ContainerServiceforEC2Role = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" + AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" + } + + vpc_zone_identifier = module.vpc.private_subnets + health_check_type = "EC2" + min_size = 0 + max_size = 2 + desired_capacity = 1 + + # https://github.com/hashicorp/terraform-provider-aws/issues/12582 + autoscaling_group_tags = { + AmazonECSManaged = true + } + + # Required for managed_termination_protection = "ENABLED" + protect_from_scale_in = true + + tags = local.tags +} + +module "autoscaling_sg" { + source = "terraform-aws-modules/security-group/aws" + version = "~> 4.0" + + name = local.name + description = "Autoscaling group security group" + vpc_id = module.vpc.vpc_id + + ingress_cidr_blocks = ["0.0.0.0/0"] + ingress_rules = ["https-443-tcp"] + + egress_rules = ["all-all"] + + tags = local.tags +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = local.name + cidr = "10.99.0.0/18" + + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + public_subnets = ["10.99.0.0/24", "10.99.1.0/24", "10.99.2.0/24"] + private_subnets = ["10.99.3.0/24", "10.99.4.0/24", "10.99.5.0/24"] + + enable_nat_gateway = false + single_nat_gateway = true + enable_dns_hostnames = true + map_public_ip_on_launch = false + + tags = local.tags +} + +resource "aws_cloudwatch_log_group" "this" { + name = "/aws/ecs/${local.name}" + retention_in_days = 7 + + tags = local.tags +} diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf new file mode 100644 index 0000000..3190f74 --- /dev/null +++ b/examples/complete/outputs.tf @@ -0,0 +1,31 @@ +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "ARN that identifies the cluster" + value = module.ecs.cluster_arn +} + +output "cluster_id" { + description = "ID that identifies the cluster" + value = module.ecs.cluster_id +} + +################################################################################ +# Cluster Capacity Providers +################################################################################ + +output "cluster_capacity_providers" { + description = "Map of cluster capacity providers attributes" + value = module.ecs.cluster_capacity_providers +} + +################################################################################ +# Capacity Provider +################################################################################ + +output "autoscaling_capacity_providers" { + description = "Map of capacity providers created and their attributes" + value = module.ecs.autoscaling_capacity_providers +} diff --git a/examples/complete-ecs/service-hello-world/main.tf b/examples/complete/service-hello-world/main.tf similarity index 60% rename from examples/complete-ecs/service-hello-world/main.tf rename to examples/complete/service-hello-world/main.tf index 91a2953..b9661bb 100644 --- a/examples/complete-ecs/service-hello-world/main.tf +++ b/examples/complete/service-hello-world/main.tf @@ -1,9 +1,9 @@ -resource "aws_cloudwatch_log_group" "hello_world" { - name = "hello_world" +resource "aws_cloudwatch_log_group" "this" { + name_prefix = "hello_world-" retention_in_days = 1 } -resource "aws_ecs_task_definition" "hello_world" { +resource "aws_ecs_task_definition" "this" { family = "hello_world" container_definitions = < +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.6 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.6 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [ecs](#module\_ecs) | ../.. | n/a | +| [ecs\_disabled](#module\_ecs\_disabled) | ../.. | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [autoscaling\_capacity\_providers](#output\_autoscaling\_capacity\_providers) | Map of capacity providers created and their attributes | +| [cluster\_arn](#output\_cluster\_arn) | ARN that identifies the cluster | +| [cluster\_capacity\_providers](#output\_cluster\_capacity\_providers) | Map of cluster capacity providers attributes | +| [cluster\_id](#output\_cluster\_id) | ID that identifies the cluster | + diff --git a/examples/fargate/main.tf b/examples/fargate/main.tf new file mode 100644 index 0000000..f800c3e --- /dev/null +++ b/examples/fargate/main.tf @@ -0,0 +1,70 @@ +provider "aws" { + region = local.region +} + +locals { + region = "eu-west-1" + name = "ecs-ex-${replace(basename(path.cwd), "_", "-")}" + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-ecs" + } +} + +################################################################################ +# Ecs Module +################################################################################ + +module "ecs" { + source = "../.." + + cluster_name = local.name + + cluster_configuration = { + execute_command_configuration = { + logging = "OVERRIDE" + log_configuration = { + # You can set a simple string and ECS will create the CloudWatch log group for you + # or you can create the resource yourself as shown here to better manage retetion, tagging, etc. + # Embedding it into the module is not trivial and therefore it is externalized + cloud_watch_log_group_name = aws_cloudwatch_log_group.this.name + } + } + } + + # Capacity provider + fargate_capacity_providers = { + FARGATE = { + default_capacity_provider_strategy = { + weight = 50 + base = 20 + } + } + FARGATE_SPOT = { + default_capacity_provider_strategy = { + weight = 50 + } + } + } + + tags = local.tags +} + +module "ecs_disabled" { + source = "../.." + + create = false +} + +################################################################################ +# Supporting Resources +################################################################################ + +resource "aws_cloudwatch_log_group" "this" { + name = "/aws/ecs/${local.name}" + retention_in_days = 7 + + tags = local.tags +} diff --git a/examples/fargate/outputs.tf b/examples/fargate/outputs.tf new file mode 100644 index 0000000..3190f74 --- /dev/null +++ b/examples/fargate/outputs.tf @@ -0,0 +1,31 @@ +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "ARN that identifies the cluster" + value = module.ecs.cluster_arn +} + +output "cluster_id" { + description = "ID that identifies the cluster" + value = module.ecs.cluster_id +} + +################################################################################ +# Cluster Capacity Providers +################################################################################ + +output "cluster_capacity_providers" { + description = "Map of cluster capacity providers attributes" + value = module.ecs.cluster_capacity_providers +} + +################################################################################ +# Capacity Provider +################################################################################ + +output "autoscaling_capacity_providers" { + description = "Map of capacity providers created and their attributes" + value = module.ecs.autoscaling_capacity_providers +} diff --git a/examples/complete-ecs/service-hello-world/outputs.tf b/examples/fargate/variables.tf similarity index 100% rename from examples/complete-ecs/service-hello-world/outputs.tf rename to examples/fargate/variables.tf diff --git a/examples/fargate/versions.tf b/examples/fargate/versions.tf new file mode 100644 index 0000000..35402be --- /dev/null +++ b/examples/fargate/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.6" + } + } +} diff --git a/main.tf b/main.tf index 76badad..b75b4ff 100644 --- a/main.tf +++ b/main.tf @@ -1,31 +1,112 @@ +################################################################################ +# Cluster +################################################################################ + resource "aws_ecs_cluster" "this" { - count = var.create_ecs ? 1 : 0 + count = var.create ? 1 : 0 + + name = var.cluster_name - name = var.name + dynamic "configuration" { + for_each = try([var.cluster_configuration], []) + + content { + dynamic "execute_command_configuration" { + for_each = try([configuration.value.execute_command_configuration], []) - setting { - name = "containerInsights" - value = var.container_insights ? "enabled" : "disabled" + content { + kms_key_id = try(execute_command_configuration.value.kms_key_id, null) + logging = try(execute_command_configuration.value.logging, "DEFAULT") + + dynamic "log_configuration" { + for_each = try([execute_command_configuration.value.log_configuration], []) + + content { + cloud_watch_encryption_enabled = try(log_configuration.value.cloud_watch_encryption_enabled, null) + cloud_watch_log_group_name = try(log_configuration.value.cloud_watch_log_group_name, null) + s3_bucket_name = try(log_configuration.value.s3_bucket_name, null) + s3_bucket_encryption_enabled = try(log_configuration.value.s3_bucket_encryption_enabled, null) + s3_key_prefix = try(log_configuration.value.s3_key_prefix, null) + } + } + } + } + } + } + + dynamic "setting" { + for_each = [var.cluster_settings] + + content { + name = setting.value.name + value = setting.value.value + } } tags = var.tags } +################################################################################ +# Cluster Capacity Providers +################################################################################ + +locals { + # We are merging these together so that we can reference the ECS capacity provider + # (ec2 autoscaling) created in this module below. Fargate is easy since its just + # static values, but the autoscaling cappacity provider needs to be self-referenced from + # within this module + cluster_capacity_providers = merge( + var.fargate_capacity_providers, + { for k, v in var.autoscaling_capacity_providers : k => merge(aws_ecs_capacity_provider.this[k], v) } + ) +} + resource "aws_ecs_cluster_capacity_providers" "this" { - count = var.create_ecs ? 1 : 0 + count = var.create ? 1 : 0 cluster_name = aws_ecs_cluster.this[0].name - - capacity_providers = var.capacity_providers + capacity_providers = distinct(concat( + [for k, v in var.fargate_capacity_providers : try(v.name, k)], + [for k, v in var.autoscaling_capacity_providers : try(v.name, k)] + )) dynamic "default_capacity_provider_strategy" { - for_each = var.default_capacity_provider_strategy + for_each = local.cluster_capacity_providers iterator = strategy content { - capacity_provider = strategy.value["capacity_provider"] - weight = lookup(strategy.value, "weight", null) - base = lookup(strategy.value, "base", null) + capacity_provider = try(strategy.value.name, strategy.key) + base = try(strategy.value.default_capacity_provider_strategy.base, null) + weight = try(strategy.value.default_capacity_provider_strategy.weight, null) } } } + +################################################################################ +# Capacity Provider - Autoscaling Group(s) +################################################################################ + +resource "aws_ecs_capacity_provider" "this" { + for_each = { for k, v in var.autoscaling_capacity_providers : k => v if var.create } + + name = try(each.value.name, each.key) + + auto_scaling_group_provider { + auto_scaling_group_arn = each.value.auto_scaling_group_arn + managed_termination_protection = try(each.value.managed_termination_protection, null) + + dynamic "managed_scaling" { + for_each = try([each.value.managed_scaling], []) + + content { + instance_warmup_period = try(managed_scaling.value.instance_warmup_period, null) + maximum_scaling_step_size = try(managed_scaling.value.maximum_scaling_step_size, null) + minimum_scaling_step_size = try(managed_scaling.value.minimum_scaling_step_size, null) + status = try(managed_scaling.value.status, null) + target_capacity = try(managed_scaling.value.target_capacity, null) + } + } + } + + tags = merge(var.tags, try(each.value.tags, {})) +} diff --git a/modules/ecs-instance-profile/README.md b/modules/ecs-instance-profile/README.md deleted file mode 100644 index ee2f957..0000000 --- a/modules/ecs-instance-profile/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# ECS instance policy - -For an EC2 instance to connect itself to ECS it needs rights to do so. - -* [Why do we need ECS instance policies?](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html) -* [ECS roles explained](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_managed_policies.html) -* [More ECS policy examples explained](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/IAMPolicyExamples.html) - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 2.48 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 2.48 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | -| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy_attachment.amazon_ssm_managed_instance_core](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_iam_role_policy_attachment.ecs_ec2_cloudwatch_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_iam_role_policy_attachment.ecs_ec2_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [include\_ssm](#input\_include\_ssm) | Whether to include policies needed for AmazonSSM | `bool` | `false` | no | -| [name](#input\_name) | Name to be used on all the resources as identifier | `string` | n/a | yes | -| [tags](#input\_tags) | A map of tags to add to instance profile role | `map(string)` | `{}` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [iam\_instance\_profile\_arn](#output\_iam\_instance\_profile\_arn) | ARN of the IAM instance profile | -| [iam\_instance\_profile\_id](#output\_iam\_instance\_profile\_id) | ID of the IAM instance profile | -| [iam\_role\_id](#output\_iam\_role\_id) | ID of the IAM role | - diff --git a/modules/ecs-instance-profile/main.tf b/modules/ecs-instance-profile/main.tf deleted file mode 100644 index a58d9cb..0000000 --- a/modules/ecs-instance-profile/main.tf +++ /dev/null @@ -1,47 +0,0 @@ -data "aws_partition" "current" {} - -resource "aws_iam_role" "this" { - name = "${var.name}_ecs_instance_role" - path = "/ecs/" - - tags = var.tags - - assume_role_policy = < +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.6 | + +## Providers + +No providers. + +## Modules + +No modules. + +## Resources + +No resources. + +## Inputs + +No inputs. + +## Outputs + +No outputs. + diff --git a/modules/service/main.tf b/modules/service/main.tf new file mode 100644 index 0000000..066066c --- /dev/null +++ b/modules/service/main.tf @@ -0,0 +1 @@ +locals {} diff --git a/modules/service/outputs.tf b/modules/service/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/service/variables.tf b/modules/service/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/service/versions.tf b/modules/service/versions.tf new file mode 100644 index 0000000..35402be --- /dev/null +++ b/modules/service/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.6" + } + } +} diff --git a/outputs.tf b/outputs.tf index 3c2c7fb..d0368ac 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,14 +1,33 @@ -output "ecs_cluster_id" { - description = "ID of the ECS Cluster" - value = concat(aws_ecs_cluster.this.*.id, [""])[0] +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "ARN that identifies the cluster" + value = try(aws_ecs_cluster.this[0].arn, null) } -output "ecs_cluster_arn" { - description = "ARN of the ECS Cluster" - value = concat(aws_ecs_cluster.this.*.arn, [""])[0] +output "cluster_id" { + description = "ID that identifies the cluster" + value = try(aws_ecs_cluster.this[0].id, null) } -output "ecs_cluster_name" { - description = "The name of the ECS cluster" - value = var.name +################################################################################ +# Cluster Capacity Providers +################################################################################ + +output "cluster_capacity_providers" { + description = "Map of cluster capacity providers attributes" + value = { + for k, v in aws_ecs_cluster_capacity_providers.this : v.id => v + } +} + +################################################################################ +# Capacity Provider - Autoscaling Group(s) +################################################################################ + +output "autoscaling_capacity_providers" { + description = "Map of autoscaling capacity providers created and their attributes" + value = aws_ecs_capacity_provider.this } diff --git a/variables.tf b/variables.tf index 3da768d..dd66323 100644 --- a/variables.tf +++ b/variables.tf @@ -1,35 +1,52 @@ -variable "create_ecs" { - description = "Controls if ECS should be created" +variable "create" { + description = "Determines whether resources will be created (affects all resources)" type = bool default = true } -variable "name" { - description = "Name to be used on all the resources as identifier, also the name of the ECS cluster" +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +################################################################################ +# Cluster +################################################################################ + +variable "cluster_name" { + description = "Name of the cluster (up to 255 letters, numbers, hyphens, and underscores)" type = string - default = null + default = "" } -variable "capacity_providers" { - description = "List of short names of one or more capacity providers to associate with the cluster. Valid values also include FARGATE and FARGATE_SPOT." - type = list(string) - default = [] +variable "cluster_configuration" { + description = "The execute command configuration for the cluster" + type = any + default = {} } -variable "default_capacity_provider_strategy" { - description = "The capacity provider strategy to use by default for the cluster. Can be one or more." - type = list(map(any)) - default = [] +variable "cluster_settings" { + description = "Configuration block(s) with cluster settings. For example, this can be used to enable CloudWatch Container Insights for a cluster" + type = map(string) + default = { + name = "containerInsights" + value = "enabled" + } } -variable "container_insights" { - description = "Controls if ECS Cluster has container insights enabled" - type = bool - default = false +################################################################################ +# Capacity Providers +################################################################################ + +variable "fargate_capacity_providers" { + description = "Map of Fargate capacity provider definitions to use for the cluster" + type = any + default = {} } -variable "tags" { - description = "A map of tags to add to ECS Cluster" - type = map(string) +variable "autoscaling_capacity_providers" { + description = "Map of autoscaling capacity provider definitons to create for the cluster" + type = any default = {} } diff --git a/versions.tf b/versions.tf index 538b915..35402be 100644 --- a/versions.tf +++ b/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 0.13.1" + required_version = ">= 1.0" required_providers { aws = { source = "hashicorp/aws" - version = ">= 3.74" + version = ">= 4.6" } } }