diff --git a/README.md b/README.md index 2749a8c..b402b96 100644 --- a/README.md +++ b/README.md @@ -11,34 +11,53 @@ A Terraform module to create ECS Cluster that relies on self-managed EC2 instanc ## Providers -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | 5.57.0 | +No providers. ## Modules -No modules. +| Name | Source | Version | +|------|--------|---------| +| [asg](#module\_asg) | ./modules/asg | n/a | +| [cluster](#module\_cluster) | ./modules/cluster | n/a | ## Resources -| Name | Type | -|------|------| -| [aws_ecs_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster) | resource | +No resources. ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [asg\_create\_launch\_template](#input\_asg\_create\_launch\_template) | Either to create a Launch Template to associate with the Autoscaling group | `bool` | `true` | no | +| [asg\_desired\_capacity](#input\_asg\_desired\_capacity) | Desired capacity for the Autoscaling group | `number` | n/a | yes | +| [asg\_iam\_instance\_profile\_name](#input\_asg\_iam\_instance\_profile\_name) | Name of the IAM Instance Profile | `string` | `null` | no | +| [asg\_iam\_instance\_profile\_tags](#input\_asg\_iam\_instance\_profile\_tags) | Resource Tags for the IAM Instance Profile | `map(any)` | `{}` | no | +| [asg\_iam\_role\_name](#input\_asg\_iam\_role\_name) | Name for the IAM Role | `string` | `null` | no | +| [asg\_iam\_role\_policy\_attachments](#input\_asg\_iam\_role\_policy\_attachments) | Policy ARNs to attach to the IAM Role | `list(string)` |
[
"arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
]
| no | +| [asg\_iam\_role\_tags](#input\_asg\_iam\_role\_tags) | Resource Tags for IAM Role | `map(any)` | `{}` | no | +| [asg\_instances\_tags](#input\_asg\_instances\_tags) | Resources Tags to propagate to the Instances | `map(any)` | `{}` | no | +| [asg\_launch\_template](#input\_asg\_launch\_template) | Launch Template to use with the Autoscaling group |
object({
name = optional(string, null)
image_id = optional(string, null)
instance_type = optional(string, null)
vpc_security_group_ids = optional(list(string), [])
key_name = optional(string, null)
user_data = optional(string, null)
tags = optional(map(any), {})
})
| `{}` | no | +| [asg\_launch\_template\_id](#input\_asg\_launch\_template\_id) | Identifier of the Launch Template | `string` | `null` | no | +| [asg\_max\_size](#input\_asg\_max\_size) | Max. size for the Autoscaling group | `number` | n/a | yes | +| [asg\_min\_size](#input\_asg\_min\_size) | Min. size for the Autoscaling group | `number` | n/a | yes | +| [asg\_name](#input\_asg\_name) | Name of the Autoscaling Group | `string` | n/a | yes | +| [asg\_tags](#input\_asg\_tags) | Resources Tags for Autoscaling group | `map(any)` | `{}` | no | +| [asg\_vpc\_zone\_identifier](#input\_asg\_vpc\_zone\_identifier) | Identifiers of the VPC Subnets | `list(string)` | n/a | yes | | [cluster\_name](#input\_cluster\_name) | Name of the ECS Cluster to create | `string` | n/a | yes | -| [execute\_command\_configuration](#input\_execute\_command\_configuration) | Details of the execute command configuration |
object({
kms_key_id = optional(string)
logging = optional(string)
log_configuration = optional(object({
cloud_watch_encryption_enabled = optional(bool)
cloud_watch_log_group_name = optional(string)
s3_bucket_name = optional(string)
s3_bucket_encryption_enabled = optional(bool)
s3_key_prefix = optional(string)
}))
})
| `null` | no | -| [service\_connect\_defaults](#input\_service\_connect\_defaults) | Default Service Connect namespace |
object({
namespace = string
})
| `null` | no | -| [setting](#input\_setting) | Details of the setting configuration |
list(object({
name = string
value = string
}))
| `[]` | no | -| [tags](#input\_tags) | Resource Tags for ECS Cluster | `map(any)` | `{}` | no | +| [cluster\_setting](#input\_cluster\_setting) | Details of the setting configuration |
list(object({
name = string
value = string
}))
| `[]` | no | +| [cluster\_tags](#input\_cluster\_tags) | Resource Tags for ECS Cluster | `map(any)` | `{}` | no | ## Outputs | Name | Description | |------|-------------| +| [asg\_arn](#output\_asg\_arn) | ARN of the Autoscaling group | +| [asg\_iam\_instance\_profile\_arn](#output\_asg\_iam\_instance\_profile\_arn) | ARN of the IAM Instance Profile being used with the Launch Template | +| [asg\_iam\_instance\_profile\_id](#output\_asg\_iam\_instance\_profile\_id) | Identifier of the IAM Instance Profile being used with the Launch Template | +| [asg\_iam\_role\_id](#output\_asg\_iam\_role\_id) | Identifier of the IAM Role being used with the IAM Instnace Profile | +| [asg\_id](#output\_asg\_id) | Identifier of the Autoscaling group | +| [asg\_launch\_template\_arn](#output\_asg\_launch\_template\_arn) | ARN of the Launch Template being used with the Autoscaling Group | +| [asg\_launch\_template\_id](#output\_asg\_launch\_template\_id) | Identifier of the Launch Template being used with the Autoscaling Group | | [cluster\_arn](#output\_cluster\_arn) | ARN of the ECS Cluster | | [cluster\_id](#output\_cluster\_id) | Identifier of the ECS Cluster | | [cluster\_name](#output\_cluster\_name) | Name of the ECS Cluster | diff --git a/main.tf b/main.tf index 95e48fd..fba7b2a 100644 --- a/main.tf +++ b/main.tf @@ -2,53 +2,42 @@ # ECS Cluster ################################################################################ -resource "aws_ecs_cluster" "this" { - name = var.cluster_name - - dynamic "configuration" { - for_each = var.execute_command_configuration != null != null ? [1] : [] - - content { - dynamic "execute_command_configuration" { - for_each = var.execute_command_configuration != null ? [1] : [] - - content { - kms_key_id = try(var.execute_command_configuration.kms_key_id, null) - logging = try(var.execute_command_configuration.logging, null) - - dynamic "log_configuration" { - for_each = try(var.execute_command_configuration.log_configuration, null) != null ? [1] : [] - - content { - cloud_watch_encryption_enabled = try(var.execute_command_configuration.log_configuration.cloud_watch_encryption_enabled, null) - cloud_watch_log_group_name = try(var.execute_command_configuration.log_configuration.cloud_watch_log_group_name, null) - s3_bucket_name = try(var.execute_command_configuration.log_configuration.s3_bucket_name, null) - s3_bucket_encryption_enabled = try(var.execute_command_configuration.log_configuration.s3_bucket_encryption_enabled, null) - s3_key_prefix = try(var.execute_command_configuration.log_configuration.s3_key_prefix, null) - } - } - } - } - } - } - - dynamic "service_connect_defaults" { - for_each = var.service_connect_defaults != null ? [1] : [] - - content { - namespace = var.service_connect_defaults.namespace - } - } - - dynamic "setting" { - for_each = var.setting - iterator = setting - - content { - name = setting.value.name - value = setting.value.value - } - } - - tags = var.tags +module "cluster" { + source = "./modules/cluster" + + name = var.cluster_name + setting = var.cluster_setting + tags = var.cluster_tags +} + +################################################################################ +# Autoscaling Group +################################################################################ + +module "asg" { + source = "./modules/asg" + + cluster_name = module.cluster.name + + name = var.asg_name + vpc_zone_identifier = var.asg_vpc_zone_identifier + desired_capacity = var.asg_desired_capacity + min_size = var.asg_min_size + max_size = var.asg_max_size + instances_tags = var.asg_instances_tags + tags = var.asg_tags + + # Launch Template + create_launch_template = var.asg_create_launch_template + launch_template_id = var.asg_launch_template_id + launch_template = var.asg_launch_template + + # IAM Role + iam_role_name = var.asg_iam_role_name + iam_role_policy_attachments = var.asg_iam_role_policy_attachments + iam_role_tags = var.asg_iam_role_tags + + # IAM Instance Profile + iam_instance_profile_name = var.asg_iam_instance_profile_name + iam_instance_profile_tags = var.asg_iam_instance_profile_tags } diff --git a/outputs.tf b/outputs.tf index 9fff8f1..61c35a4 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,18 +1,65 @@ -############################## +################################################################################ # ECS Cluster -############################## +################################################################################ output "cluster_id" { description = "Identifier of the ECS Cluster" - value = aws_ecs_cluster.this.id + value = module.cluster.id } output "cluster_arn" { description = "ARN of the ECS Cluster" - value = aws_ecs_cluster.this.arn + value = module.cluster.arn } output "cluster_name" { description = "Name of the ECS Cluster" - value = var.cluster_name + value = module.cluster.name +} + +################################################################################ +# Autoscaling Group +################################################################################ + +output "asg_id" { + description = "Identifier of the Autoscaling group" + value = module.asg.id +} + +output "asg_arn" { + description = "ARN of the Autoscaling group" + value = module.asg.arn +} + +################################################################################ +# Launch Template +################################################################################ + +output "asg_launch_template_id" { + description = "Identifier of the Launch Template being used with the Autoscaling Group" + value = module.asg.launch_template_id +} + +output "asg_launch_template_arn" { + description = "ARN of the Launch Template being used with the Autoscaling Group" + value = module.asg.launch_template_arn +} + +################################################################################ +# IAM Instance Profile +################################################################################ + +output "asg_iam_role_id" { + description = "Identifier of the IAM Role being used with the IAM Instnace Profile" + value = module.asg.iam_role_id +} + +output "asg_iam_instance_profile_id" { + description = "Identifier of the IAM Instance Profile being used with the Launch Template" + value = module.asg.iam_instance_profile_id +} + +output "asg_iam_instance_profile_arn" { + description = "ARN of the IAM Instance Profile being used with the Launch Template" + value = module.asg.iam_instance_profile_arn } diff --git a/variables.tf b/variables.tf index 71ee076..cceba21 100644 --- a/variables.tf +++ b/variables.tf @@ -1,37 +1,13 @@ -####################### +################################################################################ # ECS Cluster -####################### +################################################################################ variable "cluster_name" { description = "Name of the ECS Cluster to create" type = string } -variable "execute_command_configuration" { - description = "Details of the execute command configuration" - type = object({ - kms_key_id = optional(string) - logging = optional(string) - log_configuration = optional(object({ - cloud_watch_encryption_enabled = optional(bool) - cloud_watch_log_group_name = optional(string) - s3_bucket_name = optional(string) - s3_bucket_encryption_enabled = optional(bool) - s3_key_prefix = optional(string) - })) - }) - default = null -} - -variable "service_connect_defaults" { - description = "Default Service Connect namespace" - type = object({ - namespace = string - }) - default = null -} - -variable "setting" { +variable "cluster_setting" { description = "Details of the setting configuration" type = list(object({ name = string @@ -40,8 +16,144 @@ variable "setting" { default = [] } -variable "tags" { +variable "cluster_tags" { description = "Resource Tags for ECS Cluster" type = map(any) default = {} } + +################################################################################ +# Autoscaling Group +################################################################################ + +variable "asg_name" { + description = "Name of the Autoscaling Group" + type = string +} + +variable "asg_vpc_zone_identifier" { + description = "Identifiers of the VPC Subnets" + type = list(string) + + validation { + condition = alltrue([for subnet_id in var.asg_vpc_zone_identifier : startswith(subnet_id, "subnet-")]) + error_message = "Specified subnet ids must be valid subnet identifiers starting with \"subnet-\"." + } +} + +variable "asg_desired_capacity" { + description = "Desired capacity for the Autoscaling group" + type = number + + validation { + condition = var.asg_desired_capacity >= 0 + error_message = "Specified desired capacity must be a valid non-negative number." + } +} + +variable "asg_min_size" { + description = "Min. size for the Autoscaling group" + type = number + + validation { + condition = var.asg_min_size >= 0 + error_message = "Specified min. size must be a valid non-negative number." + } +} + +variable "asg_max_size" { + description = "Max. size for the Autoscaling group" + type = number + + validation { + condition = var.asg_max_size >= 0 + error_message = "Specified max. size must be a valid non-negative number." + } +} + +variable "asg_instances_tags" { + description = "Resources Tags to propagate to the Instances" + type = map(any) + default = {} +} + +variable "asg_tags" { + description = "Resources Tags for Autoscaling group" + type = map(any) + default = {} +} + +################################################################################ +### Launch Template +################################################################################ + +variable "asg_launch_template" { + description = "Launch Template to use with the Autoscaling group" + type = object({ + name = optional(string, null) + image_id = optional(string, null) + instance_type = optional(string, null) + vpc_security_group_ids = optional(list(string), []) + key_name = optional(string, null) + user_data = optional(string, null) + tags = optional(map(any), {}) + }) + default = {} +} + +variable "asg_create_launch_template" { + description = "Either to create a Launch Template to associate with the Autoscaling group" + type = bool + default = true +} + +variable "asg_launch_template_id" { + description = "Identifier of the Launch Template" + type = string + default = null + + validation { + condition = var.asg_launch_template_id == null || startswith(var.asg_launch_template_id != null ? var.asg_launch_template_id : "", "lt-") + error_message = "Specified launch template id must be valid launch template identifier starting with \"lt-\"." + } +} + +################################################################################ +### IAM Role +################################################################################ + +variable "asg_iam_role_name" { + description = "Name for the IAM Role" + type = string + default = null +} + +variable "asg_iam_role_policy_attachments" { + description = "Policy ARNs to attach to the IAM Role" + type = list(string) + default = [ + "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" + ] +} + +variable "asg_iam_role_tags" { + description = "Resource Tags for IAM Role" + type = map(any) + default = {} +} + +################################################################################ +### IAM Instance Profile +################################################################################ + +variable "asg_iam_instance_profile_name" { + description = "Name of the IAM Instance Profile" + type = string + default = null +} + +variable "asg_iam_instance_profile_tags" { + description = "Resource Tags for the IAM Instance Profile" + type = map(any) + default = {} +}