Skip to content

Conversation

@NgaNaNa
Copy link
Owner

@NgaNaNa NgaNaNa commented Jun 4, 2025

No description provided.

@github-actions
Copy link

github-actions bot commented Jun 4, 2025

Terraform Format and Style - DEV 🖌success

Terraform Initialization - DEV ⚙️success

Terraform Validation - DEV 🤖success

Terraform Plan - DEV 📖success

Show Plan

terraform
Acquiring state lock. This may take a few moments...
data.aws_iam_policy_document.ecs_instance_assume: Reading...
data.aws_ssm_parameter.ecs_ami: Reading...
data.aws_iam_policy_document.ecs_task_assume: Reading...
data.aws_iam_policy_document.ecs_instance_assume: Read complete after 0s [id=2851119427]
data.aws_iam_policy_document.ecs_task_assume: Read complete after 0s [id=1077804475]
data.aws_ssm_parameter.ecs_ami: Read complete after 0s [id=/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id]

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_autoscaling_group.ecs_asg will be created
  + resource "aws_autoscaling_group" "ecs_asg" {
      + arn                              = (known after apply)
      + availability_zones               = (known after apply)
      + default_cooldown                 = (known after apply)
      + desired_capacity                 = 1
      + force_delete                     = false
      + force_delete_warm_pool           = false
      + health_check_grace_period        = 300
      + health_check_type                = (known after apply)
      + id                               = (known after apply)
      + ignore_failed_scaling_activities = false
      + load_balancers                   = (known after apply)
      + max_size                         = 2
      + metrics_granularity              = "1Minute"
      + min_size                         = 1
      + name                             = (known after apply)
      + name_prefix                      = "dev-ecs-asg-"
      + predicted_capacity               = (known after apply)
      + protect_from_scale_in            = false
      + service_linked_role_arn          = (known after apply)
      + target_group_arns                = (known after apply)
      + vpc_zone_identifier              = [
          + "subnet-09391ee8d617ae5f6",
          + "subnet-0d8cdde6f87d9cff7",
          + "subnet-0f459a5b6dfa1d69b",
        ]
      + wait_for_capacity_timeout        = "10m"
      + warm_pool_size                   = (known after apply)

      + availability_zone_distribution (known after apply)

      + launch_template {
          + id      = (known after apply)
          + name    = (known after apply)
          + version = "$Latest"
        }

      + mixed_instances_policy (known after apply)

      + traffic_source (known after apply)
    }

  # aws_cloudwatch_log_group.ecs_logs will be created
  + resource "aws_cloudwatch_log_group" "ecs_logs" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "/ecs/node-app"
      + name_prefix       = (known after apply)
      + retention_in_days = 14
      + skip_destroy      = false
      + tags_all          = (known after apply)
    }

  # aws_ecs_capacity_provider.ecs_capacity_provider will be created
  + resource "aws_ecs_capacity_provider" "ecs_capacity_provider" {
      + arn      = (known after apply)
      + id       = (known after apply)
      + name     = "dev-ecs_capacity_provider"
      + tags_all = (known after apply)

      + auto_scaling_group_provider {
          + auto_scaling_group_arn         = (known after apply)
          + managed_draining               = (known after apply)
          + managed_termination_protection = (known after apply)

          + managed_scaling {
              + instance_warmup_period    = (known after apply)
              + maximum_scaling_step_size = 2
              + minimum_scaling_step_size = 1
              + status                    = "ENABLED"
              + target_capacity           = 100
            }
        }
    }

  # aws_ecs_cluster.ecs_cluster will be created
  + resource "aws_ecs_cluster" "ecs_cluster" {
      + arn      = (known after apply)
      + id       = (known after apply)
      + name     = "dev-ecs-cluster"
      + tags_all = (known after apply)

      + setting (known after apply)
    }

  # aws_ecs_cluster_capacity_providers.cluster_capacity_provider will be created
  + resource "aws_ecs_cluster_capacity_providers" "cluster_capacity_provider" {
      + capacity_providers = [
          + "dev-ecs_capacity_provider",
        ]
      + cluster_name       = "dev-ecs-cluster"
      + id                 = (known after apply)
    }

  # aws_ecs_service.node_app_service will be created
  + resource "aws_ecs_service" "node_app_service" {
      + availability_zone_rebalancing      = "DISABLED"
      + cluster                            = (known after apply)
      + deployment_maximum_percent         = 200
      + deployment_minimum_healthy_percent = 50
      + desired_count                      = 1
      + enable_ecs_managed_tags            = false
      + enable_execute_command             = false
      + health_check_grace_period_seconds  = 60
      + iam_role                           = (known after apply)
      + id                                 = (known after apply)
      + launch_type                        = (known after apply)
      + name                               = "dev-node-app-svc"
      + platform_version                   = (known after apply)
      + scheduling_strategy                = "REPLICA"
      + tags_all                           = (known after apply)
      + task_definition                    = (known after apply)
      + triggers                           = (known after apply)
      + wait_for_steady_state              = false

      + capacity_provider_strategy {
          + capacity_provider = "dev-ecs_capacity_provider"
          + weight            = 1
        }

      + load_balancer {
          + container_name   = "node-app"
          + container_port   = 3000
          + target_group_arn = (known after apply)
            # (1 unchanged attribute hidden)
        }

      + network_configuration {
          + assign_public_ip = false
          + security_groups  = (known after apply)
          + subnets          = [
              + "subnet-09391ee8d617ae5f6",
              + "subnet-0d8cdde6f87d9cff7",
              + "subnet-0f459a5b6dfa1d69b",
            ]
        }
    }

  # aws_ecs_task_definition.node_app_task will be created
  + resource "aws_ecs_task_definition" "node_app_task" {
      + arn                    = (known after apply)
      + arn_without_revision   = (known after apply)
      + container_definitions  = jsonencode(
            [
              + {
                  + essential        = true
                  + healthCheck      = {
                      + command     = [
                          + "CMD-SHELL",
                          + "wget -q -O - http://localhost:3000/ping || exit 1",
                        ]
                      + interval    = 30
                      + retries     = 3
                      + startPeriod = 10
                      + timeout     = 5
                    }
                  + image            = "nrampling/demo-node-app:1.0.3"
                  + logConfiguration = {
                      + logDriver = "awslogs"
                      + options   = {
                          + awslogs-group         = "/ecs/node-app"
                          + awslogs-region        = "ap-southeast-2"
                          + awslogs-stream-prefix = "ecs"
                        }
                    }
                  + name             = "node-app"
                  + portMappings     = [
                      + {
                          + containerPort = 3000
                          + protocol      = "tcp"
                        },
                    ]
                },
            ]
        )
      + cpu                    = "256"
      + enable_fault_injection = (known after apply)
      + execution_role_arn     = (known after apply)
      + family                 = "dev-node-app"
      + id                     = (known after apply)
      + memory                 = "384"
      + network_mode           = "awsvpc"
      + revision               = (known after apply)
      + skip_destroy           = false
      + tags_all               = (known after apply)
      + track_latest           = false
    }

  # aws_iam_instance_profile.ecs_instance_profile will be created
  + resource "aws_iam_instance_profile" "ecs_instance_profile" {
      + arn         = (known after apply)
      + create_date = (known after apply)
      + id          = (known after apply)
      + name        = "dev-ecs-instance-profile"
      + name_prefix = (known after apply)
      + path        = "/"
      + role        = "dev-ecs-instance"
      + tags_all    = (known after apply)
      + unique_id   = (known after apply)
    }

  # aws_iam_role.ecs_instance_role will be created
  + resource "aws_iam_role" "ecs_instance_role" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ec2.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "dev-ecs-instance"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy (known after apply)
    }

  # aws_iam_role.ecs_task_execution_role will be created
  + resource "aws_iam_role" "ecs_task_execution_role" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "ecs-tasks.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "dev-ecs-task-exec-role"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy (known after apply)
    }

  # aws_iam_role_policy_attachment.aws_managed_ecs will be created
  + resource "aws_iam_role_policy_attachment" "aws_managed_ecs" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
      + role       = "dev-ecs-instance"
    }

  # aws_iam_role_policy_attachment.ecs_exec_managed will be created
  + resource "aws_iam_role_policy_attachment" "ecs_exec_managed" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
      + role       = "dev-ecs-task-exec-role"
    }

  # aws_launch_template.ecs will be created
  + resource "aws_launch_template" "ecs" {
      + arn             = (known after apply)
      + default_version = (known after apply)
      + id              = (known after apply)
      + image_id        = (sensitive value)
      + instance_type   = "t2.micro"
      + latest_version  = (known after apply)
      + name            = (known after apply)
      + name_prefix     = "dev-ecs-"
      + tags_all        = (known after apply)
      + user_data       = "ICAgICAgIyEvYmluL2Jhc2gKICAgICAgZWNobyBFQ1NfQ0xVU1RFUj1kZXYtZWNzLWNsdXN0ZXIgPj4gL2V0Yy9lY3MvZWNzLmNvbmZpZwo="
        # (1 unchanged attribute hidden)

      + iam_instance_profile {
          + name = "dev-ecs-instance-profile"
        }

      + metadata_options (known after apply)

      + network_interfaces {
          + associate_public_ip_address = "true"
          + security_groups             = (known after apply)
        }
    }

  # aws_lb.app_alb will be created
  + resource "aws_lb" "app_alb" {
      + arn                                                          = (known after apply)
      + arn_suffix                                                   = (known after apply)
      + client_keep_alive                                            = 3600
      + desync_mitigation_mode                                       = "defensive"
      + dns_name                                                     = (known after apply)
      + drop_invalid_header_fields                                   = false
      + enable_deletion_protection                                   = false
      + enable_http2                                                 = true
      + enable_tls_version_and_cipher_suite_headers                  = false
      + enable_waf_fail_open                                         = false
      + enable_xff_client_port                                       = false
      + enable_zonal_shift                                           = false
      + enforce_security_group_inbound_rules_on_private_link_traffic = (known after apply)
      + id                                                           = (known after apply)
      + idle_timeout                                                 = 60
      + internal                                                     = (known after apply)
      + ip_address_type                                              = (known after apply)
      + load_balancer_type                                           = "application"
      + name                                                         = "dev-app-alb"
      + name_prefix                                                  = (known after apply)
      + preserve_host_header                                         = false
      + security_groups                                              = (known after apply)
      + subnets                                                      = [
          + "subnet-055583b9b74d44b56",
          + "subnet-0b317d17ef2fb7822",
          + "subnet-0e9b56625d00f6c88",
        ]
      + tags_all                                                     = (known after apply)
      + vpc_id                                                       = (known after apply)
      + xff_header_processing_mode                                   = "append"
      + zone_id                                                      = (known after apply)

      + subnet_mapping (known after apply)
    }

  # aws_lb_listener.http_listener will be created
  + resource "aws_lb_listener" "http_listener" {
      + arn                                                                   = (known after apply)
      + id                                                                    = (known after apply)
      + load_balancer_arn                                                     = (known after apply)
      + port                                                                  = 80
      + protocol                                                              = "HTTP"
      + routing_http_request_x_amzn_mtls_clientcert_header_name               = (known after apply)
      + routing_http_request_x_amzn_mtls_clientcert_issuer_header_name        = (known after apply)
      + routing_http_request_x_amzn_mtls_clientcert_leaf_header_name          = (known after apply)
      + routing_http_request_x_amzn_mtls_clientcert_serial_number_header_name = (known after apply)
      + routing_http_request_x_amzn_mtls_clientcert_subject_header_name       = (known after apply)
      + routing_http_request_x_amzn_mtls_clientcert_validity_header_name      = (known after apply)
      + routing_http_request_x_amzn_tls_cipher_suite_header_name              = (known after apply)
      + routing_http_request_x_amzn_tls_version_header_name                   = (known after apply)
      + routing_http_response_access_control_allow_credentials_header_value   = (known after apply)
      + routing_http_response_access_control_allow_headers_header_value       = (known after apply)
      + routing_http_response_access_control_allow_methods_header_value       = (known after apply)
      + routing_http_response_access_control_allow_origin_header_value        = (known after apply)
      + routing_http_response_access_control_expose_headers_header_value      = (known after apply)
      + routing_http_response_access_control_max_age_header_value             = (known after apply)
      + routing_http_response_content_security_policy_header_value            = (known after apply)
      + routing_http_response_server_enabled                                  = (known after apply)
      + routing_http_response_strict_transport_security_header_value          = (known after apply)
      + routing_http_response_x_content_type_options_header_value             = (known after apply)
      + routing_http_response_x_frame_options_header_value                    = (known after apply)
      + ssl_policy                                                            = (known after apply)
      + tags_all                                                              = (known after apply)
      + tcp_idle_timeout_seconds                                              = (known after apply)

      + default_action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }

      + mutual_authentication (known after apply)
    }

  # aws_lb_target_group.node_app_tg will be created
  + resource "aws_lb_target_group" "node_app_tg" {
      + arn                                = (known after apply)
      + arn_suffix                         = (known after apply)
      + connection_termination             = (known after apply)
      + deregistration_delay               = "300"
      + id                                 = (known after apply)
      + ip_address_type                    = (known after apply)
      + lambda_multi_value_headers_enabled = false
      + load_balancer_arns                 = (known after apply)
      + load_balancing_algorithm_type      = (known after apply)
      + load_balancing_anomaly_mitigation  = (known after apply)
      + load_balancing_cross_zone_enabled  = (known after apply)
      + name                               = "dev-app-tg"
      + name_prefix                        = (known after apply)
      + port                               = 3000
      + preserve_client_ip                 = (known after apply)
      + protocol                           = "HTTP"
      + protocol_version                   = (known after apply)
      + proxy_protocol_v2                  = false
      + slow_start                         = 0
      + tags_all                           = (known after apply)
      + target_type                        = "ip"
      + vpc_id                             = "vpc-0fabd74c01d8c9d4a"

      + health_check {
          + enabled             = true
          + healthy_threshold   = 2
          + interval            = 30
          + matcher             = "200"
          + path                = "/ping"
          + port                = "traffic-port"
          + protocol            = "HTTP"
          + timeout             = 5
          + unhealthy_threshold = 2
        }

      + stickiness (known after apply)

      + target_failover (known after apply)

      + target_group_health (known after apply)

      + target_health_state (known after apply)
    }

  # aws_security_group.alb_sg will be created
  + resource "aws_security_group" "alb_sg" {
      + arn                    = (known after apply)
      + description            = "Allow HTTP from anywhere to ALB"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
                # (1 unchanged attribute hidden)
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "HTTP from anywhere"
              + from_port        = 80
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 80
            },
        ]
      + name                   = "dev-alb-sg"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-0fabd74c01d8c9d4a"
    }

  # aws_security_group.ecs_instance_sg will be created
  + resource "aws_security_group" "ecs_instance_sg" {
      + arn                    = (known after apply)
      + description            = "ECS container instances"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow all outbound"
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = []
              + description      = "Traffic from ALB"
              + from_port        = 3000
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = (known after apply)
              + self             = false
              + to_port          = 3000
            },
        ]
      + name                   = "dev-ecs-instance-sg"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-0fabd74c01d8c9d4a"
    }

  # aws_security_group.task_sg will be created
  + resource "aws_security_group" "task_sg" {
      + arn                    = (known after apply)
      + description            = "securing each task ENIs created by ECS"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
                # (1 unchanged attribute hidden)
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = []
              + description      = "ALB to tasks"
              + from_port        = 3000
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = (known after apply)
              + self             = false
              + to_port          = 3000
            },
        ]
      + name                   = "dev-task-sg"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-0fabd74c01d8c9d4a"
    }

Plan: 19 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + alb_dns_name           = (known after apply)
  + asg_arn                = (known after apply)
  + capacity_provider_name = "dev-ecs_capacity_provider"
  + cluster_name           = "dev-ecs-cluster"
  + instance_sg_id         = (known after apply)
  + service_name           = "dev-node-app-svc"

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

*Pushed by: @NgaNaNa, Action: `pull_request`*

@NgaNaNa NgaNaNa merged commit 804e984 into main Jun 4, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants