Deployment ‐ Project Deployment - Campus-Castolo/m300 GitHub Wiki

🚀 Project Deployment Guide – AWS Fargate WordPress via Terraform & GitHub Actions

This document explains how to fully deploy your Terraform-based infrastructure and WordPress application using GitHub Actions for automation and manual Terraform commands for infrastructure management.


🧩 1. Project Overview

  • GitHub repository contains:
    • Terraform modules to provision AWS infrastructure
    • Dockerfile for WordPress image
    • GitHub Action Workflow to trigger image build + deployment on push to main

🛠️ 2. CI/CD Workflow: GitHub Actions Pipeline

Trigger

  • Push to main branch triggers .github/workflows/deploy.yml.

Steps Performed

  1. Docker Build:
    • Docker image for WordPress is built.
  2. Semantic Tagging:
    • Versioning is based on Git tags or commit SHA.
  3. Push to ECR:
    • The built Docker image is pushed to AWS Elastic Container Registry.
  4. Terraform Apply:
    • Applies infrastructure configuration to provision ECS, ALB, RDS, etc.

image


📦 3. Terraform Deployment – Step-by-Step

Prerequisites

  • AWS CLI configured (aws configure)
  • IAM user/role with access to provision ECS, ECR, RDS, CloudWatch
  • Terraform installed (terraform -v)
  • Valid .tfvars or backend configured

3.1 Initialize Terraform

terraform init

🔹 Initializes the working directory
🔹 Downloads required providers (e.g., AWS)
🔹 Should only be run once per new workspace or after dependency changes

image


3.2 Validate Terraform Plan

terraform plan -var-file="terraform.tfvars"

🔹 Shows what changes Terraform will make
🔹 Does not actually apply any changes
🔹 Used to review infrastructure changes before execution

image

var.db_instance_identifier
  The RDS DB instance identifier to snapshot.

  Enter a value:

data.archive_file.lambda_rds_snapshot_zip: Reading...
data.archive_file.lambda_rds_snapshot_zip: Read complete after 0s [id=4563f13d1ade1eb74e98cde70993a1d07ffc8f44]
aws_cloudwatch_event_rule.daily_rds_snapshot: Refreshing state... [id=daily-rds-snapshot]
aws_iam_policy.ec2_network_interface_management: Refreshing state... [id=arn:aws:iam::972364552982:policy/EC2NetworkInterfaceManagementPolicy]
aws_ecr_repository.m300: Refreshing state... [id=m300]
aws_cloudwatch_log_group.ecs_logs: Refreshing state... [id=/ecs/wordpress]
aws_ecs_cluster.wordpress_cluster: Refreshing state... [id=arn:aws:ecs:eu-central-1:972364552982:cluster/m300-wordpress-cluster]
aws_vpc.m300_vpc: Refreshing state... [id=vpc-0349d8bb104e2f8c1]
aws_iam_role.lambda_rds_snapshot: Refreshing state... [id=lambda-rds-snapshot-role]
aws_sns_topic.alarm_notifications: Refreshing state... [id=arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications]
aws_sns_topic_subscription.sms: Refreshing state... [id=arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications:9a7cd795-29f3-42f9-a558-d060334c6515]
aws_sns_topic_subscription.email: Refreshing state... [id=arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications:366c0395-f515-4421-8860-4e7e106d2238]
aws_ecr_lifecycle_policy.m300_policy: Refreshing state... [id=m300]
aws_iam_user_policy_attachment.attach_policy_to_user: Refreshing state... [id=rayan-20250416080405073300000004]
aws_iam_role_policy.lambda_rds_snapshot_policy: Refreshing state... [id=lambda-rds-snapshot-role:lambda-rds-snapshot-policy]
aws_lambda_function.rds_snapshot: Refreshing state... [id=rds-create-snapshot]
aws_route_table.public_rt: Refreshing state... [id=rtb-0ab327c421a07527f]
aws_route_table.private_rt: Refreshing state... [id=rtb-03f09e5c0136a1c4c]
aws_internet_gateway.igw: Refreshing state... [id=igw-0582f76bf00f416e7]
aws_subnet.private_2: Refreshing state... [id=subnet-0cdefcb5136f9f215]
aws_subnet.public_1: Refreshing state... [id=subnet-0fd5375056cf1d96a]
aws_security_group.security_group-ecs-wordpress: Refreshing state... [id=sg-0748a919f785bc22d]
aws_security_group.security_group-db: Refreshing state... [id=sg-0178ac15e777d29fc]
aws_lb_target_group.ecs_tg: Refreshing state... [id=arn:aws:elasticloadbalancing:eu-central-1:972364552982:targetgroup/ecs-target-group/2ce01d984bfdff21]
aws_security_group.security_group-alb: Refreshing state... [id=sg-0b0fba4d23e3f94ad]
aws_subnet.private_1: Refreshing state... [id=subnet-02be1ea5ff7662ab9]
aws_subnet.public_2: Refreshing state... [id=subnet-05396761b8c123d11]
aws_route.public_internet_access: Refreshing state... [id=r-rtb-0ab327c421a07527f1080289494]
aws_security_group_rule.db1_to_db2_replication: Refreshing state... [id=sgrule-159754606]
aws_security_group_rule.ecs_to_db: Refreshing state... [id=sgrule-853142860]
aws_route_table_association.public_1_assoc: Refreshing state... [id=rtbassoc-0ca1233b4d3bb1727]
aws_route_table_association.private_2_assoc: Refreshing state... [id=rtbassoc-055eb459e12b3b3d4]
aws_route_table_association.private_1_assoc: Refreshing state... [id=rtbassoc-06b8917dcd82f9468]
aws_db_subnet_group.wordpress_db_subnet_group: Refreshing state... [id=terraform-20250416080404118700000003]
aws_route_table_association.public_2_assoc: Refreshing state... [id=rtbassoc-0f36583ae43dd1a41]
aws_lb.ecs_alb: Refreshing state... [id=arn:aws:elasticloadbalancing:eu-central-1:972364552982:loadbalancer/app/ecs-alb/e4306e7e6b61bcb3]
aws_lambda_permission.allow_eventbridge: Refreshing state... [id=AllowExecutionFromEventBridge]
aws_cloudwatch_event_target.lambda_rds_snapshot: Refreshing state... [id=daily-rds-snapshot-InvokeLambda]
aws_cloudwatch_metric_alarm.alb_5xx_errors: Refreshing state... [id=ALB5xxErrors]
aws_lb_listener.ecs_listener: Refreshing state... [id=arn:aws:elasticloadbalancing:eu-central-1:972364552982:listener/app/ecs-alb/e4306e7e6b61bcb3/d2b388dfb261f35c]
aws_db_instance.wordpress_db_1: Refreshing state... [id=db-AV7SHEF3SRTAAM6BB7BKYUXWKI]
aws_ecs_task_definition.wordpress_task: Refreshing state... [id=wordpress-task]
aws_cloudwatch_metric_alarm.rds_low_storage: Refreshing state... [id=LowRDSStorage]
aws_db_instance.wordpress_db_2: Refreshing state... [id=db-N2FC2LHIWPNW2NVCR4IM6DBNW4]
aws_ecs_service.wordpress_service: Refreshing state... [id=arn:aws:ecs:eu-central-1:972364552982:service/m300-wordpress-cluster/wordpress-service]
aws_cloudwatch_dashboard.main: Refreshing state... [id=WordPressMonitoringDashboard]
aws_cloudwatch_metric_alarm.ecs_cpu_high: Refreshing state... [id=HighECSCPUUtilization]
aws_cloudwatch_metric_alarm.demo_trigger_alarm: Refreshing state... [id=DemoTriggerAlways]

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

Terraform will perform the following actions:

  # aws_cloudwatch_log_group.vpc_flow_logs will be created
  + resource "aws_cloudwatch_log_group" "vpc_flow_logs" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "/aws/vpc/flow-logs"
      + name_prefix       = (known after apply)
      + retention_in_days = 14
      + skip_destroy      = false
      + tags_all          = (known after apply)
    }

  # aws_cloudwatch_metric_alarm.demo_trigger_alarm will be updated in-place
  ~ resource "aws_cloudwatch_metric_alarm" "demo_trigger_alarm" {
      ~ actions_enabled                       = false -> true
        id                                    = "DemoTriggerAlways"
        tags                                  = {}
        # (21 unchanged attributes hidden)
    }

  # aws_flow_log.vpc will be created
  + resource "aws_flow_log" "vpc" {
      + arn                      = (known after apply)
      + iam_role_arn             = (known after apply)
      + id                       = (known after apply)
      + log_destination          = (known after apply)
      + log_destination_type     = "cloud-watch-logs"
      + log_format               = (known after apply)
      + log_group_name           = (known after apply)
      + max_aggregation_interval = 600
      + tags_all                 = (known after apply)
      + traffic_type             = "ALL"
      + vpc_id                   = "vpc-0349d8bb104e2f8c1"
    }

  # aws_flow_log.vpc_logs will be created
  + resource "aws_flow_log" "vpc_logs" {
      + arn                      = (known after apply)
      + id                       = (known after apply)
      + log_destination          = (known after apply)
      + log_destination_type     = "cloud-watch-logs"
      + log_format               = (known after apply)
      + log_group_name           = (known after apply)
      + max_aggregation_interval = 600
      + tags_all                 = (known after apply)
      + traffic_type             = "ALL"
      + vpc_id                   = "vpc-0349d8bb104e2f8c1"
    }

  # aws_iam_role.vpc_flow_logs will be created
  + resource "aws_iam_role" "vpc_flow_logs" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "vpc-flow-logs.amazonaws.com"
                        }
                      + Sid       = ""
                    },
                ]
              + 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                  = "vpc-flow-logs-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.vpc_flow_logs_policy will be created
  + resource "aws_iam_role_policy" "vpc_flow_logs_policy" {
      + id          = (known after apply)
      + name        = "vpc-flow-logs-policy"
      + name_prefix = (known after apply)
      + policy      = jsonencode(
            {
              + Statement = [
                  + {
                      + Action   = [
                          + "logs:CreateLogStream",
                          + "logs:PutLogEvents",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + role        = (known after apply)
    }

  # aws_sns_topic_subscription.email will be created
  + resource "aws_sns_topic_subscription" "email" {
      + arn                             = (known after apply)
      + confirmation_timeout_in_minutes = 1
      + confirmation_was_authenticated  = (known after apply)
      + endpoint                        = "[email protected]"
      + endpoint_auto_confirms          = false
      + filter_policy_scope             = (known after apply)
      + id                              = (known after apply)
      + owner_id                        = (known after apply)
      + pending_confirmation            = (known after apply)
      + protocol                        = "email"
      + raw_message_delivery            = false
      + topic_arn                       = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications"
    }

Plan: 6 to add, 1 to change, 0 to destroy.

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

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.

3.3 Apply Terraform Changes

terraform apply -var-file="terraform.tfvars"

🔹 Creates or updates resources based on current Terraform state
🔹 Prompts before execution (unless -auto-approve is used)
🔹 Used after verifying plan output

image


3.4 Destroy Terraform Resources

terraform destroy -var-file="terraform.tfvars"

🔹 Removes all resources created by your Terraform configuration
🔹 Use only when tearing down the environment completely (e.g., demo resets)

📸 Insert screenshot of destroyed resources confirmation

  - cluster                            = "arn:aws:ecs:eu-central-1:972364552982:cluster/m300-wordpress-cluster" -> null
      - deployment_maximum_percent         = 200 -> null
      - deployment_minimum_healthy_percent = 50 -> null
      - desired_count                      = 2 -> null
      - enable_ecs_managed_tags            = false -> null
      - enable_execute_command             = false -> null
      - health_check_grace_period_seconds  = 60 -> null
      - iam_role                           = "/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS" -> null
      - id                                 = "arn:aws:ecs:eu-central-1:972364552982:service/m300-wordpress-cluster/wordpress-service" -> null
      - launch_type                        = "FARGATE" -> null
      - name                               = "wordpress-service" -> null
      - platform_version                   = "LATEST" -> null
      - propagate_tags                     = "NONE" -> null
      - scheduling_strategy                = "REPLICA" -> null
      - tags                               = {} -> null
      - tags_all                           = {} -> null
      - task_definition                    = "arn:aws:ecs:eu-central-1:972364552982:task-definition/wordpress-task:11" -> null
      - triggers                           = {} -> null
      - wait_for_steady_state              = false -> null

      - deployment_circuit_breaker {
          - enable   = false -> null
          - rollback = false -> null
        }

      - deployment_controller {
          - type = "ECS" -> null
        }

      - load_balancer {
          - container_name   = "wordpress" -> null
          - container_port   = 80 -> null
          - target_group_arn = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:targetgroup/ecs-target-group/2ce01d984bfdff21" -> null
            # (1 unchanged attribute hidden)
        }

      - network_configuration {
          - assign_public_ip = true -> null
          - security_groups  = [
              - "sg-0748a919f785bc22d",
            ] -> null
          - subnets          = [
              - "subnet-05396761b8c123d11",
              - "subnet-0fd5375056cf1d96a",
            ] -> null
        }
    }

  # aws_ecs_task_definition.wordpress_task will be destroyed
  - resource "aws_ecs_task_definition" "wordpress_task" {
      - arn                      = "arn:aws:ecs:eu-central-1:972364552982:task-definition/wordpress-task:11" -> null
      - arn_without_revision     = "arn:aws:ecs:eu-central-1:972364552982:task-definition/wordpress-task" -> null
      - container_definitions    = (sensitive value) -> null
      - cpu                      = "512" -> null
      - enable_fault_injection   = false -> null
      - execution_role_arn       = "arn:aws:iam::972364552982:role/Administrator" -> null
      - family                   = "wordpress-task" -> null
      - id                       = "wordpress-task" -> null
      - memory                   = "1024" -> null
      - network_mode             = "awsvpc" -> null
      - requires_compatibilities = [
          - "FARGATE",
        ] -> null
      - revision                 = 11 -> null
      - skip_destroy             = false -> null
      - tags                     = {} -> null
      - tags_all                 = {} -> null
      - task_role_arn            = "arn:aws:iam::972364552982:role/Administrator" -> null
      - track_latest             = false -> null
        # (2 unchanged attributes hidden)
    }

  # aws_flow_log.vpc will be destroyed
  - resource "aws_flow_log" "vpc" {
      - arn                        = "arn:aws:ec2:eu-central-1:972364552982:vpc-flow-log/fl-02ef55fa1cbaed713" -> null
      - iam_role_arn               = "arn:aws:iam::972364552982:role/vpc-flow-logs-role" -> null
      - id                         = "fl-02ef55fa1cbaed713" -> null
      - log_destination            = "arn:aws:logs:eu-central-1:972364552982:log-group:/aws/vpc/flow-logs" -> null
      - log_destination_type       = "cloud-watch-logs" -> null
      - log_format                 = "${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}" -> null
      - log_group_name             = "/aws/vpc/flow-logs" -> null
      - max_aggregation_interval   = 600 -> null
      - tags                       = {} -> null
      - tags_all                   = {} -> null
      - traffic_type               = "ALL" -> null
      - vpc_id                     = "vpc-0349d8bb104e2f8c1" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_iam_policy.ec2_network_interface_management will be destroyed
  - resource "aws_iam_policy" "ec2_network_interface_management" {
      - arn              = "arn:aws:iam::972364552982:policy/EC2NetworkInterfaceManagementPolicy" -> null
      - attachment_count = 1 -> null
      - description      = "Allows managing EC2 network interfaces (for RDS ENI detachments)" -> null
      - id               = "arn:aws:iam::972364552982:policy/EC2NetworkInterfaceManagementPolicy" -> null
      - name             = "EC2NetworkInterfaceManagementPolicy" -> null
      - path             = "/" -> null
      - policy           = jsonencode(
            {
              - Statement = [
                  - {
                      - Action   = [
                          - "ec2:DescribeNetworkInterfaces",
                          - "ec2:DetachNetworkInterface",
                          - "ec2:DeleteNetworkInterface",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - policy_id        = "ANPA6EZLRTMLFYPYSPP3F" -> null
      - tags             = {} -> null
      - tags_all         = {} -> null
        # (1 unchanged attribute hidden)
    }

  # aws_iam_role.lambda_rds_snapshot will be destroyed
  - resource "aws_iam_role" "lambda_rds_snapshot" {
      - arn                   = "arn:aws:iam::972364552982:role/lambda-rds-snapshot-role" -> null
      - assume_role_policy    = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "sts:AssumeRole"
                      - Effect    = "Allow"
                      - Principal = {
                          - Service = "lambda.amazonaws.com"
                        }
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - create_date           = "2025-04-16T08:04:04Z" -> null
      - force_detach_policies = false -> null
      - id                    = "lambda-rds-snapshot-role" -> null
      - managed_policy_arns   = [] -> null
      - max_session_duration  = 3600 -> null
      - name                  = "lambda-rds-snapshot-role" -> null
      - path                  = "/" -> null
      - tags                  = {} -> null
      - tags_all              = {} -> null
      - unique_id             = "AROA6EZLRTMLKHFPIXU3Y" -> null
        # (3 unchanged attributes hidden)

      - inline_policy {
          - name   = "lambda-rds-snapshot-policy" -> null
          - policy = jsonencode(
                {
                  - Statement = [
                      - {
                          - Action   = [
                              - "rds:CreateDBSnapshot",
                              - "rds:ListTagsForResource",
                              - "rds:AddTagsToResource",
                              - "rds:DescribeDBInstances",
                            ]
                          - Effect   = "Allow"
                          - Resource = "*"
                        },
                      - {
                          - Action   = [
                              - "logs:CreateLogGroup",
                              - "logs:CreateLogStream",
                              - "logs:PutLogEvents",
                            ]
                          - Effect   = "Allow"
                          - Resource = "*"
                        },
                    ]
                  - Version   = "2012-10-17"
                }
            ) -> null
        }
    }

  # aws_iam_role.vpc_flow_logs will be destroyed
  - resource "aws_iam_role" "vpc_flow_logs" {
      - arn                   = "arn:aws:iam::972364552982:role/vpc-flow-logs-role" -> null
      - assume_role_policy    = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "sts:AssumeRole"
                      - Effect    = "Allow"
                      - Principal = {
                          - Service = "vpc-flow-logs.amazonaws.com"
                        }
                      - Sid       = ""
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - create_date           = "2025-04-22T13:22:03Z" -> null
      - force_detach_policies = false -> null
      - id                    = "vpc-flow-logs-role" -> null
      - managed_policy_arns   = [] -> null
      - max_session_duration  = 3600 -> null
      - name                  = "vpc-flow-logs-role" -> null
      - path                  = "/" -> null
      - tags                  = {} -> null
      - tags_all              = {} -> null
      - unique_id             = "AROA6EZLRTMLHE3V5AKSS" -> null
        # (3 unchanged attributes hidden)

      - inline_policy {
          - name   = "vpc-flow-logs-policy" -> null
          - policy = jsonencode(
                {
                  - Statement = [
                      - {
                          - Action   = [
                              - "logs:CreateLogStream",
                              - "logs:PutLogEvents",
                            ]
                          - Effect   = "Allow"
                          - Resource = "*"
                        },
                    ]
                  - Version   = "2012-10-17"
                }
            ) -> null
        }
    }

  # aws_iam_role_policy.lambda_rds_snapshot_policy will be destroyed
  - resource "aws_iam_role_policy" "lambda_rds_snapshot_policy" {
      - id          = "lambda-rds-snapshot-role:lambda-rds-snapshot-policy" -> null
      - name        = "lambda-rds-snapshot-policy" -> null
      - policy      = jsonencode(
            {
              - Statement = [
                  - {
                      - Action   = [
                          - "rds:CreateDBSnapshot",
                          - "rds:ListTagsForResource",
                          - "rds:AddTagsToResource",
                          - "rds:DescribeDBInstances",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                    },
                  - {
                      - Action   = [
                          - "logs:CreateLogGroup",
                          - "logs:CreateLogStream",
                          - "logs:PutLogEvents",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - role        = "lambda-rds-snapshot-role" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_iam_role_policy.vpc_flow_logs_policy will be destroyed
  - resource "aws_iam_role_policy" "vpc_flow_logs_policy" {
      - id          = "vpc-flow-logs-role:vpc-flow-logs-policy" -> null
      - name        = "vpc-flow-logs-policy" -> null
      - policy      = jsonencode(
            {
              - Statement = [
                  - {
                      - Action   = [
                          - "logs:CreateLogStream",
                          - "logs:PutLogEvents",
                        ]
                      - Effect   = "Allow"
                      - Resource = "*"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> null
      - role        = "vpc-flow-logs-role" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_iam_user_policy_attachment.attach_policy_to_user will be destroyed
  - resource "aws_iam_user_policy_attachment" "attach_policy_to_user" {
      - id         = "rayan-20250416080405073300000004" -> null
      - policy_arn = "arn:aws:iam::972364552982:policy/EC2NetworkInterfaceManagementPolicy" -> null
      - user       = "rayan" -> null
    }

  # aws_internet_gateway.igw will be destroyed
  - resource "aws_internet_gateway" "igw" {
      - arn      = "arn:aws:ec2:eu-central-1:972364552982:internet-gateway/igw-0582f76bf00f416e7" -> null
      - id       = "igw-0582f76bf00f416e7" -> null
      - owner_id = "972364552982" -> null
      - tags     = {
          - "Name" = "M300-IGW"
        } -> null
      - tags_all = {
          - "Name" = "M300-IGW"
        } -> null
      - vpc_id   = "vpc-0349d8bb104e2f8c1" -> null
    }

  # aws_lambda_function.rds_snapshot will be destroyed
  - resource "aws_lambda_function" "rds_snapshot" {
      - architectures                  = [
          - "x86_64",
        ] -> null
      - arn                            = "arn:aws:lambda:eu-central-1:972364552982:function:rds-create-snapshot" -> null
      - code_sha256                    = "79edIgwZgM9Itn88YWpLuC6y8IZ9GT2H/s9T7hx5C8E=" -> null
      - filename                       = "./lambda.zip" -> null
      - function_name                  = "rds-create-snapshot" -> null
      - handler                        = "rds_snapshot.lambda_handler" -> null
      - id                             = "rds-create-snapshot" -> null
      - invoke_arn                     = "arn:aws:apigateway:eu-central-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-central-1:972364552982:function:rds-create-snapshot/invocations" -> null
      - last_modified                  = "2025-04-16T08:04:13.809+0000" -> null
      - layers                         = [] -> null
      - memory_size                    = 128 -> null
      - package_type                   = "Zip" -> null
      - publish                        = false -> null
      - qualified_arn                  = "arn:aws:lambda:eu-central-1:972364552982:function:rds-create-snapshot:$LATEST" -> null
      - qualified_invoke_arn           = "arn:aws:apigateway:eu-central-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-central-1:972364552982:function:rds-create-snapshot:$LATEST/invocations" -> null
      - reserved_concurrent_executions = -1 -> null
      - role                           = "arn:aws:iam::972364552982:role/lambda-rds-snapshot-role" -> null
      - runtime                        = "python3.11" -> null
      - skip_destroy                   = false -> null
      - source_code_size               = 525 -> null
      - tags                           = {} -> null
      - tags_all                       = {} -> null
      - timeout                        = 30 -> null
      - version                        = "$LATEST" -> null
        # (7 unchanged attributes hidden)

      - environment {
          - variables = {
              - "RDS_INSTANCE_IDENTIFIER" = null
            } -> null
        }

      - ephemeral_storage {
          - size = 512 -> null
        }

      - logging_config {
          - log_format            = "Text" -> null
          - log_group             = "/aws/lambda/rds-create-snapshot" -> null
            # (2 unchanged attributes hidden)
        }

      - tracing_config {
          - mode = "PassThrough" -> null
        }
    }

  # aws_lambda_permission.allow_eventbridge will be destroyed
  - resource "aws_lambda_permission" "allow_eventbridge" {
      - action              = "lambda:InvokeFunction" -> null
      - function_name       = "rds-create-snapshot" -> null
      - id                  = "AllowExecutionFromEventBridge" -> null
      - principal           = "events.amazonaws.com" -> null
      - source_arn          = "arn:aws:events:eu-central-1:972364552982:rule/daily-rds-snapshot" -> null
      - statement_id        = "AllowExecutionFromEventBridge" -> null
        # (2 unchanged attributes hidden)
    }

  # aws_lb.ecs_alb will be destroyed
  - resource "aws_lb" "ecs_alb" {
      - arn                                                          = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:loadbalancer/app/ecs-alb/e4306e7e6b61bcb3" -> null
      - arn_suffix                                                   = "app/ecs-alb/e4306e7e6b61bcb3" -> null
      - client_keep_alive                                            = 3600 -> null
      - desync_mitigation_mode                                       = "defensive" -> null
      - dns_name                                                     = "ecs-alb-68511347.eu-central-1.elb.amazonaws.com" -> null
      - drop_invalid_header_fields                                   = false -> null
      - enable_cross_zone_load_balancing                             = true -> null
      - enable_deletion_protection                                   = false -> null
      - enable_http2                                                 = true -> null
      - enable_tls_version_and_cipher_suite_headers                  = false -> null
      - enable_waf_fail_open                                         = false -> null
      - enable_xff_client_port                                       = false -> null
      - enable_zonal_shift                                           = false -> null
      - id                                                           = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:loadbalancer/app/ecs-alb/e4306e7e6b61bcb3" -> null
      - idle_timeout                                                 = 60 -> null
      - internal                                                     = false -> null
      - ip_address_type                                              = "ipv4" -> null
      - load_balancer_type                                           = "application" -> null
      - name                                                         = "ecs-alb" -> null
      - preserve_host_header                                         = false -> null
      - security_groups                                              = [
          - "sg-0b0fba4d23e3f94ad",
        ] -> null
      - subnets                                                      = [
          - "subnet-05396761b8c123d11",
          - "subnet-0fd5375056cf1d96a",
        ] -> null
      - tags                                                         = {
          - "Name" = "ECS Load Balancer"
        } -> null
      - tags_all                                                     = {
          - "Name" = "ECS Load Balancer"
        } -> null
      - vpc_id                                                       = "vpc-0349d8bb104e2f8c1" -> null
      - xff_header_processing_mode                                   = "append" -> null
      - zone_id                                                      = "Z215JYRZR1TBD5" -> null
        # (3 unchanged attributes hidden)

      - access_logs {
          - enabled = false -> null
            # (2 unchanged attributes hidden)
        }

      - connection_logs {
          - enabled = false -> null
            # (2 unchanged attributes hidden)
        }

      - subnet_mapping {
          - subnet_id            = "subnet-05396761b8c123d11" -> null
            # (4 unchanged attributes hidden)
        }
      - subnet_mapping {
          - subnet_id            = "subnet-0fd5375056cf1d96a" -> null
            # (4 unchanged attributes hidden)
        }
    }

  # aws_lb_listener.ecs_listener will be destroyed
  - resource "aws_lb_listener" "ecs_listener" {
      - arn                                                                 = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:listener/app/ecs-alb/e4306e7e6b61bcb3/d2b388dfb261f35c" -> null
      - id                                                                  = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:listener/app/ecs-alb/e4306e7e6b61bcb3/d2b388dfb261f35c" -> null
      - load_balancer_arn                                                   = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:loadbalancer/app/ecs-alb/e4306e7e6b61bcb3" -> null
      - port                                                                = 80 -> null
      - protocol                                                            = "HTTP" -> null
      - routing_http_response_server_enabled                                = false -> null
      - tags                                                                = {} -> null
      - tags_all                                                            = {} -> null
        # (11 unchanged attributes hidden)

      - default_action {
          - order            = 1 -> null
          - target_group_arn = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:targetgroup/ecs-target-group/2ce01d984bfdff21" -> null
          - type             = "forward" -> null
        }
    }

  # aws_lb_target_group.ecs_tg will be destroyed
  - resource "aws_lb_target_group" "ecs_tg" {
      - arn                                = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:targetgroup/ecs-target-group/2ce01d984bfdff21" -> null
      - arn_suffix                         = "targetgroup/ecs-target-group/2ce01d984bfdff21" -> null
      - deregistration_delay               = "300" -> null
      - id                                 = "arn:aws:elasticloadbalancing:eu-central-1:972364552982:targetgroup/ecs-target-group/2ce01d984bfdff21" -> null
      - ip_address_type                    = "ipv4" -> null
      - lambda_multi_value_headers_enabled = false -> null
      - load_balancer_arns                 = [
          - "arn:aws:elasticloadbalancing:eu-central-1:972364552982:loadbalancer/app/ecs-alb/e4306e7e6b61bcb3",
        ] -> null
      - load_balancing_algorithm_type      = "round_robin" -> null
      - load_balancing_anomaly_mitigation  = "off" -> null
      - load_balancing_cross_zone_enabled  = "use_load_balancer_configuration" -> null
      - name                               = "ecs-target-group" -> null
      - port                               = 80 -> null
      - protocol                           = "HTTP" -> null
      - protocol_version                   = "HTTP1" -> null
      - proxy_protocol_v2                  = false -> null
      - slow_start                         = 0 -> null
      - tags                               = {} -> null
      - tags_all                           = {} -> null
      - target_type                        = "ip" -> null
      - vpc_id                             = "vpc-0349d8bb104e2f8c1" -> null
        # (1 unchanged attribute hidden)

      - health_check {
          - enabled             = true -> null
          - healthy_threshold   = 2 -> null
          - interval            = 30 -> null
          - matcher             = "200-399" -> null
          - path                = "/" -> null
          - port                = "traffic-port" -> null
          - protocol            = "HTTP" -> null
          - timeout             = 5 -> null
          - unhealthy_threshold = 3 -> null
        }

      - stickiness {
          - cookie_duration = 86400 -> null
          - enabled         = false -> null
          - type            = "lb_cookie" -> null
            # (1 unchanged attribute hidden)
        }

      - target_failover {}

      - target_group_health {
          - dns_failover {
              - minimum_healthy_targets_count      = "1" -> null
              - minimum_healthy_targets_percentage = "off" -> null
            }
          - unhealthy_state_routing {
              - minimum_healthy_targets_count      = 1 -> null
              - minimum_healthy_targets_percentage = "off" -> null
            }
        }

      - target_health_state {}
    }

  # aws_route.public_internet_access will be destroyed
  - resource "aws_route" "public_internet_access" {
      - destination_cidr_block      = "0.0.0.0/0" -> null
      - gateway_id                  = "igw-0582f76bf00f416e7" -> null
      - id                          = "r-rtb-0ab327c421a07527f1080289494" -> null
      - origin                      = "CreateRoute" -> null
      - route_table_id              = "rtb-0ab327c421a07527f" -> null
      - state                       = "active" -> null
        # (13 unchanged attributes hidden)
    }

  # aws_route_table.private_rt will be destroyed
  - resource "aws_route_table" "private_rt" {
      - arn              = "arn:aws:ec2:eu-central-1:972364552982:route-table/rtb-03f09e5c0136a1c4c" -> null
      - id               = "rtb-03f09e5c0136a1c4c" -> null
      - owner_id         = "972364552982" -> null
      - propagating_vgws = [] -> null
      - route            = [] -> null
      - tags             = {
          - "Name" = "M300-Private-RT"
        } -> null
      - tags_all         = {
          - "Name" = "M300-Private-RT"
        } -> null
      - vpc_id           = "vpc-0349d8bb104e2f8c1" -> null
    }

  # aws_route_table.public_rt will be destroyed
  - resource "aws_route_table" "public_rt" {
      - arn              = "arn:aws:ec2:eu-central-1:972364552982:route-table/rtb-0ab327c421a07527f" -> null
      - id               = "rtb-0ab327c421a07527f" -> null
      - owner_id         = "972364552982" -> null
      - propagating_vgws = [] -> null
      - route            = [
          - {
              - cidr_block                 = "0.0.0.0/0"
              - gateway_id                 = "igw-0582f76bf00f416e7"
                # (11 unchanged attributes hidden)
            },
        ] -> null
      - tags             = {
          - "Name" = "M300-Public-RT"
        } -> null
      - tags_all         = {
          - "Name" = "M300-Public-RT"
        } -> null
      - vpc_id           = "vpc-0349d8bb104e2f8c1" -> null
    }

  # aws_route_table_association.private_1_assoc will be destroyed
  - resource "aws_route_table_association" "private_1_assoc" {
      - id             = "rtbassoc-06b8917dcd82f9468" -> null
      - route_table_id = "rtb-03f09e5c0136a1c4c" -> null
      - subnet_id      = "subnet-02be1ea5ff7662ab9" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_route_table_association.private_2_assoc will be destroyed
  - resource "aws_route_table_association" "private_2_assoc" {
      - id             = "rtbassoc-055eb459e12b3b3d4" -> null
      - route_table_id = "rtb-03f09e5c0136a1c4c" -> null
      - subnet_id      = "subnet-0cdefcb5136f9f215" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_route_table_association.public_1_assoc will be destroyed
  - resource "aws_route_table_association" "public_1_assoc" {
      - id             = "rtbassoc-0ca1233b4d3bb1727" -> null
      - route_table_id = "rtb-0ab327c421a07527f" -> null
      - subnet_id      = "subnet-0fd5375056cf1d96a" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_route_table_association.public_2_assoc will be destroyed
  - resource "aws_route_table_association" "public_2_assoc" {
      - id             = "rtbassoc-0f36583ae43dd1a41" -> null
      - route_table_id = "rtb-0ab327c421a07527f" -> null
      - subnet_id      = "subnet-05396761b8c123d11" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_security_group.security_group-alb will be destroyed
  - resource "aws_security_group" "security_group-alb" {
      - arn                    = "arn:aws:ec2:eu-central-1:972364552982:security-group/sg-0b0fba4d23e3f94ad" -> null
      - description            = "Allow public HTTP to ALB" -> null
      - egress                 = [
          - {
              - cidr_blocks      = [
                  - "0.0.0.0/0",
                ]
              - description      = "Allow all outbound from ALB"
              - from_port        = 0
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "-1"
              - security_groups  = []
              - self             = false
              - to_port          = 0
            },
        ] -> null
      - id                     = "sg-0b0fba4d23e3f94ad" -> null
      - ingress                = [
          - {
              - cidr_blocks      = [
                  - "0.0.0.0/0",
                ]
              - description      = "Public access to ALB"
              - from_port        = 80
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = false
              - to_port          = 80
            },
        ] -> null
      - name                   = "security-group-alb" -> null
      - owner_id               = "972364552982" -> null
      - revoke_rules_on_delete = false -> null
      - tags                   = {
          - "Name" = "ALB SG"
        } -> null
      - tags_all               = {
          - "Name" = "ALB SG"
        } -> null
      - vpc_id                 = "vpc-0349d8bb104e2f8c1" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_security_group.security_group-db will be destroyed
  - resource "aws_security_group" "security_group-db" {
      - arn                    = "arn:aws:ec2:eu-central-1:972364552982:security-group/sg-0178ac15e777d29fc" -> null
      - description            = "Allow internal access to RDS from ECS and replication" -> null
      - 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
            },
        ] -> null
      - id                     = "sg-0178ac15e777d29fc" -> null
      - ingress                = [
          - {
              - cidr_blocks      = []
              - description      = "Allow MySQL from ECS to RDS"
              - from_port        = 3306
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = [
                  - "sg-0748a919f785bc22d",
                ]
              - self             = false
              - to_port          = 3306
            },
          - {
              - cidr_blocks      = []
              - description      = "Allow RDS DB1 to replicate to DB2"
              - from_port        = 3306
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = true
              - to_port          = 3306
            },
        ] -> null
      - name                   = "security-group-db" -> null
      - owner_id               = "972364552982" -> null
      - revoke_rules_on_delete = false -> null
      - tags                   = {
          - "Name" = "RDS DB SG"
        } -> null
      - tags_all               = {
          - "Name" = "RDS DB SG"
        } -> null
      - vpc_id                 = "vpc-0349d8bb104e2f8c1" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_security_group.security_group-ecs-wordpress will be destroyed
  - resource "aws_security_group" "security_group-ecs-wordpress" {
      - arn                    = "arn:aws:ec2:eu-central-1:972364552982:security-group/sg-0748a919f785bc22d" -> null
      - description            = "Allow HTTP traffic to ECS WordPress containers" -> null
      - egress                 = [
          - {
              - cidr_blocks      = [
                  - "0.0.0.0/0",
                ]
              - description      = "Allow all outbound traffic"
              - from_port        = 0
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "-1"
              - security_groups  = []
              - self             = false
              - to_port          = 0
            },
        ] -> null
      - id                     = "sg-0748a919f785bc22d" -> null
      - ingress                = [
          - {
              - cidr_blocks      = [
                  - "0.0.0.0/0",
                ]
              - description      = "Allow public HTTP traffic"
              - from_port        = 80
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = false
              - to_port          = 80
            },
        ] -> null
      - name                   = "security-group-ecs-wordpress" -> null
      - owner_id               = "972364552982" -> null
      - revoke_rules_on_delete = false -> null
      - tags                   = {
          - "Name" = "ECS WordPress SG"
        } -> null
      - tags_all               = {
          - "Name" = "ECS WordPress SG"
        } -> null
      - vpc_id                 = "vpc-0349d8bb104e2f8c1" -> null
        # (1 unchanged attribute hidden)
    }

  # aws_security_group_rule.db1_to_db2_replication will be destroyed
  - resource "aws_security_group_rule" "db1_to_db2_replication" {
      - description              = "Allow RDS DB1 to replicate to DB2" -> null
      - from_port                = 3306 -> null
      - id                       = "sgrule-159754606" -> null
      - protocol                 = "tcp" -> null
      - security_group_id        = "sg-0178ac15e777d29fc" -> null
      - security_group_rule_id   = "sgr-0a808e0c0556f6ef8" -> null
      - self                     = false -> null
      - source_security_group_id = "sg-0178ac15e777d29fc" -> null
      - to_port                  = 3306 -> null
      - type                     = "ingress" -> null
    }

  # aws_security_group_rule.ecs_to_db will be destroyed
  - resource "aws_security_group_rule" "ecs_to_db" {
      - description              = "Allow MySQL from ECS to RDS" -> null
      - from_port                = 3306 -> null
      - id                       = "sgrule-853142860" -> null
      - protocol                 = "tcp" -> null
      - security_group_id        = "sg-0178ac15e777d29fc" -> null
      - security_group_rule_id   = "sgr-0d0488d8d39f657c2" -> null
      - self                     = false -> null
      - source_security_group_id = "sg-0748a919f785bc22d" -> null
      - to_port                  = 3306 -> null
      - type                     = "ingress" -> null
    }

  # aws_sns_topic.alarm_notifications will be destroyed
  - resource "aws_sns_topic" "alarm_notifications" {
      - application_success_feedback_sample_rate = 0 -> null
      - arn                                      = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications" -> null        
      - content_based_deduplication              = false -> null
      - fifo_topic                               = false -> null
      - firehose_success_feedback_sample_rate    = 0 -> null
      - http_success_feedback_sample_rate        = 0 -> null
      - id                                       = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications" -> null        
      - lambda_success_feedback_sample_rate      = 0 -> null
      - name                                     = "cloudwatch-alarm-notifications" -> null
      - owner                                    = "972364552982" -> null
      - policy                                   = jsonencode(
            {
              - Id        = "__default_policy_ID"
              - Statement = [
                  - {
                      - Action    = [
                          - "SNS:GetTopicAttributes",
                          - "SNS:SetTopicAttributes",
                          - "SNS:AddPermission",
                          - "SNS:RemovePermission",
                          - "SNS:DeleteTopic",
                          - "SNS:Subscribe",
                          - "SNS:ListSubscriptionsByTopic",
                          - "SNS:Publish",
                        ]
                      - Condition = {
                          - StringEquals = {
                              - "AWS:SourceOwner" = "972364552982"
                            }
                        }
                      - Effect    = "Allow"
                      - Principal = {
                          - AWS = "*"
                        }
                      - Resource  = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications"
                      - Sid       = "__default_statement_ID"
                    },
                ]
              - Version   = "2008-10-17"
            }
        ) -> null
      - signature_version                        = 0 -> null
      - sqs_success_feedback_sample_rate         = 0 -> null
      - tags                                     = {} -> null
      - tags_all                                 = {} -> null
        # (17 unchanged attributes hidden)
    }

  # aws_sns_topic_subscription.email will be destroyed
  - resource "aws_sns_topic_subscription" "email" {
      - arn                             = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications:eaa75126-dc00-42c5-b6ef-71c9cd61935b" -> null
      - confirmation_timeout_in_minutes = 1 -> null
      - confirmation_was_authenticated  = false -> null
      - endpoint                        = "[email protected]" -> null
      - endpoint_auto_confirms          = false -> null
      - id                              = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications:eaa75126-dc00-42c5-b6ef-71c9cd61935b" -> null
      - owner_id                        = "972364552982" -> null
      - pending_confirmation            = true -> null
      - protocol                        = "email" -> null
      - raw_message_delivery            = false -> null
      - topic_arn                       = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications" -> null
        # (6 unchanged attributes hidden)
    }

  # aws_sns_topic_subscription.sms will be destroyed
  - resource "aws_sns_topic_subscription" "sms" {
      - arn                             = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications:9a7cd795-29f3-42f9-a558-d060334c6515" -> null
      - confirmation_timeout_in_minutes = 1 -> null
      - confirmation_was_authenticated  = true -> null
      - endpoint                        = "+41786957297" -> null
      - endpoint_auto_confirms          = false -> null
      - id                              = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications:9a7cd795-29f3-42f9-a558-d060334c6515" -> null
      - owner_id                        = "972364552982" -> null
      - pending_confirmation            = false -> null
      - protocol                        = "sms" -> null
      - raw_message_delivery            = false -> null
      - topic_arn                       = "arn:aws:sns:eu-central-1:972364552982:cloudwatch-alarm-notifications" -> null
        # (6 unchanged attributes hidden)
    }

  # aws_subnet.private_1 will be destroyed
  - resource "aws_subnet" "private_1" {
      - arn                                            = "arn:aws:ec2:eu-central-1:972364552982:subnet/subnet-02be1ea5ff7662ab9" -> null 
      - assign_ipv6_address_on_creation                = false -> null
      - availability_zone                              = "eu-central-1a" -> null
      - availability_zone_id                           = "euc1-az2" -> null
      - cidr_block                                     = "10.0.3.0/24" -> null
      - enable_dns64                                   = false -> null
      - enable_lni_at_device_index                     = 0 -> null
      - enable_resource_name_dns_a_record_on_launch    = false -> null
      - enable_resource_name_dns_aaaa_record_on_launch = false -> null
      - id                                             = "subnet-02be1ea5ff7662ab9" -> null
      - ipv6_native                                    = false -> null
      - map_customer_owned_ip_on_launch                = false -> null
      - map_public_ip_on_launch                        = false -> null
      - owner_id                                       = "972364552982" -> null
      - private_dns_hostname_type_on_launch            = "ip-name" -> null
      - tags                                           = {
          - "Name" = "M300-Private-1"
        } -> null
      - tags_all                                       = {
          - "Name" = "M300-Private-1"
        } -> null
      - vpc_id                                         = "vpc-0349d8bb104e2f8c1" -> null
        # (4 unchanged attributes hidden)
    }

  # aws_subnet.private_2 will be destroyed
  - resource "aws_subnet" "private_2" {
      - arn                                            = "arn:aws:ec2:eu-central-1:972364552982:subnet/subnet-0cdefcb5136f9f215" -> null 
      - assign_ipv6_address_on_creation                = false -> null
      - availability_zone                              = "eu-central-1b" -> null
      - availability_zone_id                           = "euc1-az3" -> null
      - cidr_block                                     = "10.0.4.0/24" -> null
      - enable_dns64                                   = false -> null
      - enable_lni_at_device_index                     = 0 -> null
      - enable_resource_name_dns_a_record_on_launch    = false -> null
      - enable_resource_name_dns_aaaa_record_on_launch = false -> null
      - id                                             = "subnet-0cdefcb5136f9f215" -> null
      - ipv6_native                                    = false -> null
      - map_customer_owned_ip_on_launch                = false -> null
      - map_public_ip_on_launch                        = false -> null
      - owner_id                                       = "972364552982" -> null
      - private_dns_hostname_type_on_launch            = "ip-name" -> null
      - tags                                           = {
          - "Name" = "M300-Private-2"
        } -> null
      - tags_all                                       = {
          - "Name" = "M300-Private-2"
        } -> null
      - vpc_id                                         = "vpc-0349d8bb104e2f8c1" -> null
        # (4 unchanged attributes hidden)
    }

  # aws_subnet.public_1 will be destroyed
  - resource "aws_subnet" "public_1" {
      - arn                                            = "arn:aws:ec2:eu-central-1:972364552982:subnet/subnet-0fd5375056cf1d96a" -> null 
      - assign_ipv6_address_on_creation                = false -> null
      - availability_zone                              = "eu-central-1a" -> null
      - availability_zone_id                           = "euc1-az2" -> null
      - cidr_block                                     = "10.0.1.0/24" -> null
      - enable_dns64                                   = false -> null
      - enable_lni_at_device_index                     = 0 -> null
      - enable_resource_name_dns_a_record_on_launch    = false -> null
      - enable_resource_name_dns_aaaa_record_on_launch = false -> null
      - id                                             = "subnet-0fd5375056cf1d96a" -> null
      - ipv6_native                                    = false -> null
      - map_customer_owned_ip_on_launch                = false -> null
      - map_public_ip_on_launch                        = true -> null
      - owner_id                                       = "972364552982" -> null
      - private_dns_hostname_type_on_launch            = "ip-name" -> null
      - tags                                           = {
          - "Name" = "M300-Public-1"
        } -> null
      - tags_all                                       = {
          - "Name" = "M300-Public-1"
        } -> null
      - vpc_id                                         = "vpc-0349d8bb104e2f8c1" -> null
        # (4 unchanged attributes hidden)
    }

  # aws_subnet.public_2 will be destroyed
  - resource "aws_subnet" "public_2" {
      - arn                                            = "arn:aws:ec2:eu-central-1:972364552982:subnet/subnet-05396761b8c123d11" -> null 
      - assign_ipv6_address_on_creation                = false -> null
      - availability_zone                              = "eu-central-1b" -> null
      - availability_zone_id                           = "euc1-az3" -> null
      - cidr_block                                     = "10.0.2.0/24" -> null
      - enable_dns64                                   = false -> null
      - enable_lni_at_device_index                     = 0 -> null
      - enable_resource_name_dns_a_record_on_launch    = false -> null
      - enable_resource_name_dns_aaaa_record_on_launch = false -> null
      - id                                             = "subnet-05396761b8c123d11" -> null
      - ipv6_native                                    = false -> null
      - map_customer_owned_ip_on_launch                = false -> null
      - map_public_ip_on_launch                        = true -> null
      - owner_id                                       = "972364552982" -> null
      - private_dns_hostname_type_on_launch            = "ip-name" -> null
      - tags                                           = {
          - "Name" = "M300-Public-2"
        } -> null
      - tags_all                                       = {
          - "Name" = "M300-Public-2"
        } -> null
      - vpc_id                                         = "vpc-0349d8bb104e2f8c1" -> null
        # (4 unchanged attributes hidden)
    }

  # aws_vpc.m300_vpc will be destroyed
  - resource "aws_vpc" "m300_vpc" {
      - arn                                  = "arn:aws:ec2:eu-central-1:972364552982:vpc/vpc-0349d8bb104e2f8c1" -> null
      - assign_generated_ipv6_cidr_block     = false -> null
      - cidr_block                           = "10.0.0.0/16" -> null
      - default_network_acl_id               = "acl-0f37d483e90f3e99c" -> null
      - default_route_table_id               = "rtb-0fbee49d1374c0089" -> null
      - default_security_group_id            = "sg-008b65f8856cb1338" -> null
      - dhcp_options_id                      = "dopt-0896cec43cabad679" -> null
      - enable_dns_hostnames                 = true -> null
      - enable_dns_support                   = true -> null
      - enable_network_address_usage_metrics = false -> null
      - id                                   = "vpc-0349d8bb104e2f8c1" -> null
      - instance_tenancy                     = "default" -> null
      - ipv6_netmask_length                  = 0 -> null
      - main_route_table_id                  = "rtb-0fbee49d1374c0089" -> null
      - owner_id                             = "972364552982" -> null
      - tags                                 = {
          - "Name" = "M300-VPC"
        } -> null
      - tags_all                             = {
          - "Name" = "M300-VPC"
        } -> null
        # (4 unchanged attributes hidden)
    }

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

Changes to Outputs:
  - alb_arn_suffix                  = "app" -> null
  - alb_dns_name                    = "ecs-alb-68511347.eu-central-1.elb.amazonaws.com" -> null
  - debug_db_host                   = "wordpress-db-subnet02-eu-central-1.cd8a4eacyjel.eu-central-1.rds.amazonaws.com" -> null
  - wordpress_db_1_backup_retention = 7 -> null

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

🌍 4. AWS Infrastructure – Result

  • ECS Fargate service running Dockerized WordPress
  • Load-balanced via Application Load Balancer (ALB)
  • MySQL data hosted on encrypted RDS instance
  • ECS autoscaling configured (if implemented)
  • Monitoring and alerts available via CloudWatch + SNS
  • Backups scheduled via Lambda

🟢 Final ALB URL:

http://ecs-alb-729435232.eu-central-1.elb.amazonaws.com/

image

note: its in indonesian because i clicked through the setup process.


✅ Deployment Summary

Step Purpose Command/Trigger
Initialize Download providers and setup backend terraform init
Preview Check plan without changes terraform plan
Deploy Create/update cloud infrastructure terraform apply
Destroy Tear down all infrastructure terraform destroy
Automate CI/CD deploys on commit GitHub Action Trigger

This guide helps any engineer replicate, audit, or rebuild your entire infrastructure from scratch with full visibility, security, and automation.