Skip to content

feat: add trivy scan to plan to staging#7

Merged
lrasata merged 25 commits intomainfrom
feat/add-trivy-to-cicd-pipeline
Jan 7, 2026
Merged

feat: add trivy scan to plan to staging#7
lrasata merged 25 commits intomainfrom
feat/add-trivy-to-cicd-pipeline

Conversation

@lrasata
Copy link
Owner

@lrasata lrasata commented Jan 6, 2026

No description provided.

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

Terraform Plan (staging - All Layers)

security

Click to expand
[command]/home/runner/work/_temp/f787c79e-6c76-4548-8baf-fa5e2e3f6cf1/terraform-bin show -no-color tfplan

Changes to Outputs:
  + datasource_password     = (sensitive value)
  + datasource_username     = (sensitive value)
  + file_upload_auth_secret = (sensitive value)
  + locations_auth_secret   = (sensitive value)
  + secrets_arn             = (sensitive value)

You can apply this plan to save these new output values to the Terraform
state, without changing any real infrastructure.
::debug::Terraform exited with code 0.
::debug::stdout: %0AChanges to Outputs:%0A  + datasource_password     = (sensitive value)%0A  + datasource_username     = (sensitive value)%0A  + file_upload_auth_secret = (sensitive value)%0A  + locations_auth_secret   = (sensitive value)%0A  + secrets_arn             = (sensitive value)%0A%0AYou can apply this plan to save these new output values to the Terraform%0Astate, without changing any real infrastructure.%0A
::debug::stderr: 
::debug::exitcode: 0

networking

Click to expand
[command]/home/runner/work/_temp/f25e37a6-71f2-425b-aaf4-5bea8d36e28c/terraform-bin show -no-color tfplan

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_vpc_endpoint.dynamodb_gw_endpoint will be created
  + resource "aws_vpc_endpoint" "dynamodb_gw_endpoint" {
      + arn                   = (known after apply)
      + cidr_blocks           = (known after apply)
      + dns_entry             = (known after apply)
      + id                    = (known after apply)
      + ip_address_type       = (known after apply)
      + network_interface_ids = (known after apply)
      + owner_id              = (known after apply)
      + policy                = (known after apply)
      + prefix_list_id        = (known after apply)
      + private_dns_enabled   = (known after apply)
      + region                = "eu-central-1"
      + requester_managed     = (known after apply)
      + route_table_ids       = (known after apply)
      + security_group_ids    = (known after apply)
      + service_name          = "com.amazonaws.eu-central-1.dynamodb"
      + service_region        = (known after apply)
      + state                 = (known after apply)
      + subnet_ids            = (known after apply)
      + tags                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + vpc_endpoint_type     = "Gateway"
      + vpc_id                = (known after apply)

      + dns_options (known after apply)

      + subnet_configuration (known after apply)
    }

  # aws_vpc_endpoint.s3_gw_endpoint will be created
  + resource "aws_vpc_endpoint" "s3_gw_endpoint" {
      + arn                   = (known after apply)
      + cidr_blocks           = (known after apply)
      + dns_entry             = (known after apply)
      + id                    = (known after apply)
      + ip_address_type       = (known after apply)
      + network_interface_ids = (known after apply)
      + owner_id              = (known after apply)
      + policy                = (known after apply)
      + prefix_list_id        = (known after apply)
      + private_dns_enabled   = (known after apply)
      + region                = "eu-central-1"
      + requester_managed     = (known after apply)
      + route_table_ids       = (known after apply)
      + security_group_ids    = (known after apply)
      + service_name          = "com.amazonaws.eu-central-1.s3"
      + service_region        = (known after apply)
      + state                 = (known after apply)
      + subnet_ids            = (known after apply)
      + tags                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + vpc_endpoint_type     = "Gateway"
      + vpc_id                = (known after apply)

      + dns_options (known after apply)

      + subnet_configuration (known after apply)
    }

  # module.vpc.aws_default_network_acl.this[0] will be created
  + resource "aws_default_network_acl" "this" {
      + arn                    = (known after apply)
      + default_network_acl_id = (known after apply)
      + id                     = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "eu-central-1"
      + tags                   = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + tags_all               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + vpc_id                 = (known after apply)

      + egress {
          + action          = "allow"
          + from_port       = 0
          + ipv6_cidr_block = "::/0"
          + protocol        = "-1"
          + rule_no         = 101
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }
      + egress {
          + action          = "allow"
          + cidr_block      = "0.0.0.0/0"
          + from_port       = 0
          + protocol        = "-1"
          + rule_no         = 100
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }

      + ingress {
          + action          = "allow"
          + from_port       = 0
          + ipv6_cidr_block = "::/0"
          + protocol        = "-1"
          + rule_no         = 101
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }
      + ingress {
          + action          = "allow"
          + cidr_block      = "0.0.0.0/0"
          + from_port       = 0
          + protocol        = "-1"
          + rule_no         = 100
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }
    }

  # module.vpc.aws_default_route_table.default[0] will be created
  + resource "aws_default_route_table" "default" {
      + arn                    = (known after apply)
      + default_route_table_id = (known after apply)
      + id                     = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "eu-central-1"
      + route                  = (known after apply)
      + tags                   = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + tags_all               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + vpc_id                 = (known after apply)

      + timeouts {
          + create = "5m"
          + update = "5m"
        }
    }

  # module.vpc.aws_default_security_group.this[0] will be created
  + resource "aws_default_security_group" "this" {
      + arn                    = (known after apply)
      + description            = (known after apply)
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = (known after apply)
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "eu-central-1"
      + revoke_rules_on_delete = false
      + tags                   = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + tags_all               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + vpc_id                 = (known after apply)
    }

  # module.vpc.aws_eip.nat[0] will be created
  + resource "aws_eip" "nat" {
      + allocation_id        = (known after apply)
      + arn                  = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = "vpc"
      + id                   = (known after apply)
      + instance             = (known after apply)
      + ipam_pool_id         = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + ptr_record           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + region               = "eu-central-1"
      + tags                 = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1a"
        }
      + tags_all             = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1a"
        }
    }

  # module.vpc.aws_eip.nat[1] will be created
  + resource "aws_eip" "nat" {
      + allocation_id        = (known after apply)
      + arn                  = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = "vpc"
      + id                   = (known after apply)
      + instance             = (known after apply)
      + ipam_pool_id         = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + ptr_record           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + region               = "eu-central-1"
      + tags                 = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1b"
        }
      + tags_all             = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1b"
        }
    }

  # module.vpc.aws_eip.nat[2] will be created
  + resource "aws_eip" "nat" {
      + allocation_id        = (known after apply)
      + arn                  = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = "vpc"
      + id                   = (known after apply)
      + instance             = (known after apply)
      + ipam_pool_id         = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + ptr_record           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + region               = "eu-central-1"
      + tags                 = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1c"
        }
      + tags_all             = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1c"
        }
    }

  # module.vpc.aws_internet_gateway.this[0] will be created
  + resource "aws_internet_gateway" "this" {
      + arn      = (known after apply)
      + id       = (known after apply)
      + owner_id = (known after apply)
      + region   = "eu-central-1"
      + tags     = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc"
        }
      + tags_all = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc"
        }
      + vpc_id   = (known after apply)
    }

  # module.vpc.aws_nat_gateway.this[0] will be created
  + resource "aws_nat_gateway" "this" {
      + allocation_id                      = (known after apply)
      + association_id                     = (known after apply)
      + auto_provision_zones               = (known after apply)
      + auto_scaling_ips                   = (known after apply)
      + availability_mode                  = (known after apply)
      + connectivity_type                  = "public"
      + id                                 = (known after apply)
      + network_interface_id               = (known after apply)
      + private_ip                         = (known after apply)
      + public_ip                          = (known after apply)
      + region                             = "eu-central-1"
      + regional_nat_gateway_address       = (known after apply)
      + regional_nat_gateway_auto_mode     = (known after apply)
      + route_table_id                     = (known after apply)
      + secondary_allocation_ids           = (known after apply)
      + secondary_private_ip_address_count = (known after apply)
      + secondary_private_ip_addresses     = (known after apply)
      + subnet_id                          = (known after apply)
      + tags                               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1a"
        }
      + tags_all                           = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1a"
        }
      + vpc_id                             = (known after apply)
    }

  # module.vpc.aws_nat_gateway.this[1] will be created
  + resource "aws_nat_gateway" "this" {
      + allocation_id    

...(truncated)

database

Click to expand
[command]/home/runner/work/_temp/40cbb8bc-7c9d-4b05-a0f7-eb89d3063278/terraform-bin show -no-color tfplan

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_cloudwatch_metric_alarm.rds_availability will be created
  + resource "aws_cloudwatch_metric_alarm" "rds_availability" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when DB has CPU utilization of 0% for 5 minutes- RDS is potentially down"
      + alarm_name                            = "staging-RDS-CPUUtilization-Down"
      + arn                                   = (known after apply)
      + comparison_operator                   = "LessThanThreshold"
      + dimensions                            = {
          + "DBInstanceIdentifier" = "staging-trip-planner-app-db"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "CPUUtilization"
      + namespace                             = "AWS/RDS"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 0
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.rds_free_storage will be created
  + resource "aws_cloudwatch_metric_alarm" "rds_free_storage" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when RDS free storage space is low"
      + alarm_name                            = "staging-RDS-Free-Storage-Low"
      + arn                                   = (known after apply)
      + comparison_operator                   = "LessThanThreshold"
      + dimensions                            = {
          + "DBInstanceIdentifier" = "staging-trip-planner-app-db"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 2
      + id                                    = (known after apply)
      + metric_name                           = "FreeStorageSpace"
      + namespace                             = "AWS/RDS"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 2000000000
      + treat_missing_data                    = "missing"
    }

  # aws_db_subnet_group.rds_subnet_group will be created
  + resource "aws_db_subnet_group" "rds_subnet_group" {
      + arn                     = (known after apply)
      + description             = "Managed by Terraform"
      + id                      = (known after apply)
      + name                    = "staging-trip-planner-app-rds-subnet-group"
      + name_prefix             = (known after apply)
      + region                  = "eu-central-1"
      + subnet_ids              = [
          + "subnet-placeholder1",
          + "subnet-placeholder2",
        ]
      + supported_network_types = (known after apply)
      + tags                    = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + vpc_id                  = (known after apply)
    }

  # aws_security_group.sg_rds will be created
  + resource "aws_security_group" "sg_rds" {
      + arn                    = (known after apply)
      + description            = "Allow ECS tasks access to database and internet"
      + 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      = []
              + from_port        = 5432
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 5432
                # (1 unchanged attribute hidden)
            },
        ]
      + name                   = "staging-trip-planner-app-rds-sg"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "eu-central-1"
      + revoke_rules_on_delete = false
      + tags                   = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + vpc_id                 = "vpc-placeholder"
    }

  # module.rds_sns_alerts.aws_kms_key.sns_cmk will be created
  + resource "aws_kms_key" "sns_cmk" {
      + arn                                = (known after apply)
      + bypass_policy_lockout_safety_check = false
      + customer_master_key_spec           = "SYMMETRIC_DEFAULT"
      + description                        = "SNS CMK"
      + enable_key_rotation                = true
      + id                                 = (known after apply)
      + is_enabled                         = true
      + key_id                             = (known after apply)
      + key_usage                          = "ENCRYPT_DECRYPT"
      + multi_region                       = (known after apply)
      + policy                             = (known after apply)
      + region                             = "eu-central-1"
      + rotation_period_in_days            = (known after apply)
      + tags                               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                           = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
    }

  # module.rds_sns_alerts.aws_sns_topic.alerts will be created
  + resource "aws_sns_topic" "alerts" {
      + arn                         = (known after apply)
      + beginning_archive_time      = (known after apply)
      + content_based_deduplication = false
      + fifo_throughput_scope       = (known after apply)
      + fifo_topic                  = false
      + id                          = (known after apply)
      + kms_master_key_id           = (known after apply)
      + name                        = "staging-trip-planner-app-staging-trip-planner-app-db-sns-topic"
      + name_prefix                 = (known after apply)
      + owner                       = (known after apply)
      + policy                      = (known after apply)
      + region                      = "eu-central-1"
      + signature_version           = (known after apply)
      + tags                        = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Service"     = "staging-trip-planner-app-db"
        }
      + tags_all                    = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Service"     = "staging-trip-planner-app-db"
        }
      + tracing_config              = (known after apply)
    }

  # module.rds_sns_alerts.aws_sns_topic_subscription.alerts_email will be created
  + resource "aws_sns_topic_subscription" "alerts_email" {
      + arn                             = (known after apply)
      + confirmation_timeout_in_minutes = 1
      + confirmation_was_authenticated  = (known after apply)
      + endpoint                        = "rmliantsoa@gmail.com"
      + 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
      + region                          = "eu-central-1"
      + topic_arn                       = (known after apply)
    }

  # module.db.module.db_instance.aws_db_instance.this[0] will be created
  + resource "aws_db_instance" "this" {
      + address                               = (known after apply)
      + allocated_storage                     = 20
      + allow_major_version_upgrade           = false
      + apply_immediately                     = false
      + arn                                   = (known after apply)
      + auto_minor_version_upgrade            = true
      + availability_zone                     = (known after apply)
      + backup_retention_period               = 0
      + backup_target                         = (known after apply)
      + backup_window                         = (known after apply)
      + ca_cert_identifier                    = (known after apply)
      + character_set_name                    = (known after apply)
      + copy_tags_to_snapshot                 = true
      + database_insights_mode                = (known after apply)
      + db_name                               = "stagingtripplannerappdbname"
      + db_subnet_group_name                  = "staging-trip-planner-app-rds-subnet-group"
      + dedicated_log_volume                  = false
      + delete_automated_backups              = true
      + deletion_protection                   = true
      + domain_fqdn                           = (known after apply)
      + endpoint                              = (known after apply)
      + engine                                = "postgres"
      + engine_lifecycle_support              = (known after apply)
      + engine_version                        = "15"
      + engine_version_actual                 = (known after apply)
      + final_snapshot_identifier             = (known after apply)
      + hosted_zone_id                        = (known after apply)
      + iam_database_authentication_enabled   = false
      + id                                    = (known after apply)
      + identifier                            = "staging-trip-planner-app-db"
      + identifier_prefix                     = (known after apply)
      + instance_class                        = "db.t3.micro"
      + iops                                  = (known after apply)
      + kms_key_id                            = (known after apply)
      + latest_restorable_time                = (known after apply)
      + license_model                         = (known after apply)
      + listener_endpoint                     = (known after apply)
      + maintenance_window                    = (known after apply)
      + manage_master_user_password           = true
      + master_user_secret                    = (known after apply)
      + master_user_secret_kms_key_id         = (known after apply)
      + max_allocated_storage                 = 0
      + monitoring_interval                   = 0
      + monitoring_role_arn                   = (known after apply)
      + multi_az                              = true
      + nchar_character_set_name              = (known after apply)
      + network_type                          = (known after apply)
      + option_group_name                     = (known after apply)
      + parameter_group_name                  = (known after apply)
      + password_wo                           = (write-only attribute)
      + performance_insights_enabled          = false
      + performance_insights_kms_key_id       = (known after apply)
      + performance_insights_retention_period = (known after apply)
      + port                                  = 5432
      + publicly_accessible                   = false
      + region                                = "eu-central-1"
      + replica_mode                          = (known after apply)
      + replicas                              = (known after apply)
      + resource_id                           = (known after apply)
      + skip_final_snapshot                   = false
      + snapshot_identifier                   = (known after apply)
      + status                                = (known after apply)
      + storage_encrypted                     = false
      + storage_throughput                    = (known after apply)
      + storage_type                          = (known after apply)
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "sta

...(truncated)

backend

Click to expand
[command]/home/runner/work/_temp/f9856183-89d2-408f-bfb5-99180b3d44c6/terraform-bin show -no-color tfplan

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_cloudwatch_metric_alarm.alb_5xx_errors will be created
  + resource "aws_cloudwatch_metric_alarm" "alb_5xx_errors" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "ALB is returning too many 5xx errors"
      + alarm_name                            = "alb-5xx-errors"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = (known after apply)
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "HTTPCode_Target_5XX_Count"
      + namespace                             = "AWS/ApplicationELB"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Sum"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 5
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.alb_high_latency will be created
  + resource "aws_cloudwatch_metric_alarm" "alb_high_latency" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "ALB latency above 2 seconds for 10 minutes"
      + alarm_name                            = "alb-high-latency"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = (known after apply)
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 2
      + id                                    = (known after apply)
      + metric_name                           = "TargetResponseTime"
      + namespace                             = "AWS/ApplicationELB"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 2
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.alb_unhealthy_hosts will be created
  + resource "aws_cloudwatch_metric_alarm" "alb_unhealthy_hosts" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "ALB target group has unhealthy hosts"
      + alarm_name                            = "staging-alb-unhealthy-hosts"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = (known after apply)
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "UnHealthyHostCount"
      + namespace                             = "AWS/ApplicationELB"
      + period                                = 60
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 0
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.ecs_cpu_high will be created
  + resource "aws_cloudwatch_metric_alarm" "ecs_cpu_high" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when ECS CPU utilization exceeds 90%"
      + alarm_name                            = "staging-trip-planner-app-ecs-service-CPUHigh"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = {
          + "ClusterName" = "staging-trip-planner-app-ecs-cluster"
          + "ServiceName" = "staging-trip-planner-app-ecs-service"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 2
      + id                                    = (known after apply)
      + metric_name                           = "CPUUtilization"
      + namespace                             = "AWS/ECS"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 90
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.ecs_memory_high will be created
  + resource "aws_cloudwatch_metric_alarm" "ecs_memory_high" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when ECS Memory utilization exceeds 90%"
      + alarm_name                            = "staging-trip-planner-app-ecs-service-MemoryHigh"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = {
          + "ClusterName" = "staging-trip-planner-app-ecs-cluster"
          + "ServiceName" = "staging-trip-planner-app-ecs-service"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 2
      + id                                    = (known after apply)
      + metric_name                           = "MemoryUtilization"
      + namespace                             = "AWS/ECS"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 90
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.ecs_unhealthy_tasks will be created
  + resource "aws_cloudwatch_metric_alarm" "ecs_unhealthy_tasks" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when ECS service has unhealthy tasks"
      + alarm_name                            = "staging-trip-planner-app-ecs-service-UnhealthyTasks"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = {
          + "ClusterName" = "staging-trip-planner-app-ecs-cluster"
          + "ServiceName" = "staging-trip-planner-app-ecs-service"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "UnhealthyTaskCount"
      + namespace                             = "AWS/ECS"
      + period                                = 60
      + region                                = "eu-central-1"
      + statistic                             = "Maximum"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 0
      + treat_missing_data                    = "missing"
    }

  # aws_wafv2_web_acl.alb_waf will be created
  + resource "aws_wafv2_web_acl" "alb_waf" {
      + application_integration_url = (known after apply)
      + arn                         = (known after apply)
      + capacity                    = (known after apply)
      + description                 = "WAF for ALB"
      + id                          = (known after apply)
      + lock_token                  = (known after apply)
      + name                        = "staging-trip-planner-app-alb-waf"
      + name_prefix                 = (known after apply)
      + region                      = "eu-central-1"
      + scope                       = "REGIONAL"
      + tags                        = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                    = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }

      + default_action {
          + allow {
            }
        }

      + rule {
          + name     = "staging-trip-planner-app-BlockHydra"
          + priority = 103

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Hydra"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockHydra"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockMasscan"
          + priority = 104

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Masscan"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockMasscan"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockNikto"
          + priority = 100

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Nikto"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockNikto"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockSQLMap"
          + priority = 101

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
      

...(truncated)

frontend

Click to expand
[command]/home/runner/work/_temp/d8bac522-5737-49e4-baef-bf448ad7f0b4/terraform-bin show -no-color tfplan

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create
 <= read (data resources)

Terraform will perform the following actions:

  # aws_cloudwatch_metric_alarm.cloudfront_5xx will be created
  + resource "aws_cloudwatch_metric_alarm" "cloudfront_5xx" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when CloudFront 5xx errors spike"
      + alarm_name                            = "staging-trip-planner-app-CloudFront-5xx-Errors-High"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = (known after apply)
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "5xxErrorRate"
      + namespace                             = "AWS/CloudFront"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 1
      + treat_missing_data                    = "missing"
    }

  # aws_wafv2_web_acl.cloudfront_waf will be created
  + resource "aws_wafv2_web_acl" "cloudfront_waf" {
      + application_integration_url = (known after apply)
      + arn                         = (known after apply)
      + capacity                    = (known after apply)
      + description                 = "WAF for CloudFront distribution of the Trip Planner app"
      + id                          = (known after apply)
      + lock_token                  = (known after apply)
      + name                        = "staging-trip-planner-app-cloudfront-waf"
      + name_prefix                 = (known after apply)
      + region                      = "us-east-1"
      + scope                       = "CLOUDFRONT"
      + tags                        = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                    = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }

      + default_action {
          + allow {
            }
        }

      + rule {
          + name     = "staging-trip-planner-app-BlockHydra"
          + priority = 13

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Hydra"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockHydra"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockMasscan"
          + priority = 14

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Masscan"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockMasscan"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockNikto"
          + priority = 10

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Nikto"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockNikto"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockSQLMap"
          + priority = 11

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "SQLMap"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockSQLMap"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockZAP"
          + priority = 12

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "ZAP"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockZAP"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-RateLimitPerIP"
          + priority = 16

          + action {
              + block {
                }
            }

          + statement {
              + rate_based_statement {
                  + aggregate_key_type    = "IP"
                  + evaluation_window_sec = 300
                  + limit                 = 1000
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-rateLimit"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-AWSManagedRulesCommonRuleSet"
          + priority = 1

          + override_action {
              + none {}
            }

          + statement {
              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesCommonRuleSet"
                  + vendor_name = "AWS"
                    # (1 unchanged attribute hidden)
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "managedRules"
              + sampled_requests_enabled   = true
            }
        }

      + visibility_config {
          + cloudwatch_metrics_enabled = true
          + metric_name                = "staging-trip-planner-app-CloudfrontWAF"
          + sampled_requests_enabled   = true
        }
    }

  # module.cloudfront.aws_cloudfront_distribution.cdn will be created
  + resource "aws_cloudfront_distribution" "cdn" {
      + aliases                         = [
          + "staging.epic-trip-planner.com",
        ]
      + arn                             = (known after apply)
      + caller_reference                = (known after apply)
      + continuous_deployment_policy_id = (known after apply)
      + default_root_object             = "index.html"
      + domain_name                     = (known after apply)
      + enabled                         = true
      + etag                            = (known after apply)
      + hosted_zone_id                  = (known after apply)
      + http_version                    = "http2"
      + id                              = (known after apply)
      + in_progress_validation_batches  = (known after apply)
      + is_ipv6_enabled                 = true
      + last_modified_time              = (known after apply)
      + logging_v1_enabled              = (known after apply)
      + price_class                     = "PriceClass_All"
      + retain_on_delete                = false
      + staging                         = false
      + status                          = (known after apply)
      + tags                            = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                        = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + trusted_key_groups              = (known after apply)
      + trusted_signers                 = (known after apply)
      + wait_for_deployment             = true
      + web_acl_id                      = (known after apply)

      + default_cache_behavior {
          + allowed_methods        = [
              + "GET",
              + "HEAD",
              + "OPTIONS",
            ]
          + cached_methods         = [
              + "GET",
              + "HEAD",
            ]
          + compress               = true
          + default_ttl            = 3600
          + max_ttl                = 86400
          + min_ttl                = 0
          + target_origin_id       = "staging-trip-planner-app-s3-static-web-files-bucket-origin"
          + trusted_key_groups     = (known after apply)
          + trusted_signers        = (known after apply)
          + viewer_protocol_policy = "redirect-to-https"

          + forwarded_values {
              + headers                 = (known after apply)
              + query_string            = false
              + query_string_cache_keys = (known after apply)

              + cookies {
                  + forward           = "none"
                  + whitelisted_names = (known after apply)
                }
            }

          + grpc_config (known after apply)

          + lambda_function_association {
              + event_type   = "viewer-request"
              + include_body = false
              + lambda_arn   = (known after apply)
            }
        }

      + ordered_cache_behavior {
          + allowed_methods        = [
              + "DELETE",
              + "GET",
              + "HEAD",
              + "OPTIONS",
              + "PATCH",
              + "POST",
              + "PUT",
            ]
          + cached_methods         = [
              + "GET",
              + "HEAD",
            ]
          + compress               = false
          + default_ttl            = 0
          + max_ttl                = 0
          + min_ttl                = 0
          + path_pattern           = "/api/*"
          + target_origin_id       = "staging-trip-planner-app-alb-origin"
          + viewer_protocol_policy = "redirect-to-https"

          + forwarded_values {
              + headers                 = (known after apply)
              + query_string            = true
              + query_string_cache_keys = (known after apply)

              + cookies {
                  + forward = "all"
                }
            }

          + grpc_config (known after apply)
        }
      + ordered_cache_behavior {
          + allowed_methods        = [
              + "DELETE",
              + "GET",
              + "HEAD",
              + "OPTIONS",
              + "PATCH",
              + "POST",
              + "PUT",
            ]
          + cached_methods         = [
              + "GET",
              + "HEAD",
            ]
          + compress               = false
          + default_ttl            = 0
          + max_ttl                = 0
          + min_ttl                = 0
          + path_pattern           = "/auth/*"
          + target_origin_id       = "staging-trip-planner-app-alb-origin"
          + viewer_protocol_pol

...(truncated)

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

✅ Ephemeral Environment Deployed Successfully

Environment: ephemeral
Domain: eph-pr-7.epic-trip-planner.com

The changes have been successfully deployed to an ephemeral environment for testing.

⚠️ Note: This environment will be automatically destroyed when the PR is merged or closed.

Copy link
Collaborator

@liantsoa-deu-droid liantsoa-deu-droid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

✅ Ephemeral Environment Deployed Successfully

Environment: ephemeral
Domain: eph-pr-7.epic-trip-planner.com

The changes have been successfully deployed to an ephemeral environment for testing.

⚠️ Note: This environment will be automatically destroyed when the PR is merged or closed.

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

Terraform Plan (staging - All Layers)

security

Click to expand
[command]/home/runner/work/_temp/3374ff15-70eb-41e4-a6b2-2e60fa93dade/terraform-bin show -no-color tfplan

Changes to Outputs:
  + datasource_password     = (sensitive value)
  + datasource_username     = (sensitive value)
  + file_upload_auth_secret = (sensitive value)
  + locations_auth_secret   = (sensitive value)
  + secrets_arn             = (sensitive value)

You can apply this plan to save these new output values to the Terraform
state, without changing any real infrastructure.
::debug::Terraform exited with code 0.
::debug::stdout: %0AChanges to Outputs:%0A  + datasource_password     = (sensitive value)%0A  + datasource_username     = (sensitive value)%0A  + file_upload_auth_secret = (sensitive value)%0A  + locations_auth_secret   = (sensitive value)%0A  + secrets_arn             = (sensitive value)%0A%0AYou can apply this plan to save these new output values to the Terraform%0Astate, without changing any real infrastructure.%0A
::debug::stderr: 
::debug::exitcode: 0

networking

Click to expand
[command]/home/runner/work/_temp/9aedd1e3-c82c-4de6-a998-8ff6a48c378b/terraform-bin show -no-color tfplan

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_vpc_endpoint.dynamodb_gw_endpoint will be created
  + resource "aws_vpc_endpoint" "dynamodb_gw_endpoint" {
      + arn                   = (known after apply)
      + cidr_blocks           = (known after apply)
      + dns_entry             = (known after apply)
      + id                    = (known after apply)
      + ip_address_type       = (known after apply)
      + network_interface_ids = (known after apply)
      + owner_id              = (known after apply)
      + policy                = (known after apply)
      + prefix_list_id        = (known after apply)
      + private_dns_enabled   = (known after apply)
      + region                = "eu-central-1"
      + requester_managed     = (known after apply)
      + route_table_ids       = (known after apply)
      + security_group_ids    = (known after apply)
      + service_name          = "com.amazonaws.eu-central-1.dynamodb"
      + service_region        = (known after apply)
      + state                 = (known after apply)
      + subnet_ids            = (known after apply)
      + tags                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + vpc_endpoint_type     = "Gateway"
      + vpc_id                = (known after apply)

      + dns_options (known after apply)

      + subnet_configuration (known after apply)
    }

  # aws_vpc_endpoint.s3_gw_endpoint will be created
  + resource "aws_vpc_endpoint" "s3_gw_endpoint" {
      + arn                   = (known after apply)
      + cidr_blocks           = (known after apply)
      + dns_entry             = (known after apply)
      + id                    = (known after apply)
      + ip_address_type       = (known after apply)
      + network_interface_ids = (known after apply)
      + owner_id              = (known after apply)
      + policy                = (known after apply)
      + prefix_list_id        = (known after apply)
      + private_dns_enabled   = (known after apply)
      + region                = "eu-central-1"
      + requester_managed     = (known after apply)
      + route_table_ids       = (known after apply)
      + security_group_ids    = (known after apply)
      + service_name          = "com.amazonaws.eu-central-1.s3"
      + service_region        = (known after apply)
      + state                 = (known after apply)
      + subnet_ids            = (known after apply)
      + tags                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + vpc_endpoint_type     = "Gateway"
      + vpc_id                = (known after apply)

      + dns_options (known after apply)

      + subnet_configuration (known after apply)
    }

  # module.vpc.aws_default_network_acl.this[0] will be created
  + resource "aws_default_network_acl" "this" {
      + arn                    = (known after apply)
      + default_network_acl_id = (known after apply)
      + id                     = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "eu-central-1"
      + tags                   = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + tags_all               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + vpc_id                 = (known after apply)

      + egress {
          + action          = "allow"
          + from_port       = 0
          + ipv6_cidr_block = "::/0"
          + protocol        = "-1"
          + rule_no         = 101
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }
      + egress {
          + action          = "allow"
          + cidr_block      = "0.0.0.0/0"
          + from_port       = 0
          + protocol        = "-1"
          + rule_no         = 100
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }

      + ingress {
          + action          = "allow"
          + from_port       = 0
          + ipv6_cidr_block = "::/0"
          + protocol        = "-1"
          + rule_no         = 101
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }
      + ingress {
          + action          = "allow"
          + cidr_block      = "0.0.0.0/0"
          + from_port       = 0
          + protocol        = "-1"
          + rule_no         = 100
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }
    }

  # module.vpc.aws_default_route_table.default[0] will be created
  + resource "aws_default_route_table" "default" {
      + arn                    = (known after apply)
      + default_route_table_id = (known after apply)
      + id                     = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "eu-central-1"
      + route                  = (known after apply)
      + tags                   = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + tags_all               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + vpc_id                 = (known after apply)

      + timeouts {
          + create = "5m"
          + update = "5m"
        }
    }

  # module.vpc.aws_default_security_group.this[0] will be created
  + resource "aws_default_security_group" "this" {
      + arn                    = (known after apply)
      + description            = (known after apply)
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = (known after apply)
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "eu-central-1"
      + revoke_rules_on_delete = false
      + tags                   = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + tags_all               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-default"
        }
      + vpc_id                 = (known after apply)
    }

  # module.vpc.aws_eip.nat[0] will be created
  + resource "aws_eip" "nat" {
      + allocation_id        = (known after apply)
      + arn                  = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = "vpc"
      + id                   = (known after apply)
      + instance             = (known after apply)
      + ipam_pool_id         = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + ptr_record           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + region               = "eu-central-1"
      + tags                 = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1a"
        }
      + tags_all             = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1a"
        }
    }

  # module.vpc.aws_eip.nat[1] will be created
  + resource "aws_eip" "nat" {
      + allocation_id        = (known after apply)
      + arn                  = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = "vpc"
      + id                   = (known after apply)
      + instance             = (known after apply)
      + ipam_pool_id         = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + ptr_record           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + region               = "eu-central-1"
      + tags                 = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1b"
        }
      + tags_all             = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1b"
        }
    }

  # module.vpc.aws_eip.nat[2] will be created
  + resource "aws_eip" "nat" {
      + allocation_id        = (known after apply)
      + arn                  = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = "vpc"
      + id                   = (known after apply)
      + instance             = (known after apply)
      + ipam_pool_id         = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + ptr_record           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + region               = "eu-central-1"
      + tags                 = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1c"
        }
      + tags_all             = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1c"
        }
    }

  # module.vpc.aws_internet_gateway.this[0] will be created
  + resource "aws_internet_gateway" "this" {
      + arn      = (known after apply)
      + id       = (known after apply)
      + owner_id = (known after apply)
      + region   = "eu-central-1"
      + tags     = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc"
        }
      + tags_all = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc"
        }
      + vpc_id   = (known after apply)
    }

  # module.vpc.aws_nat_gateway.this[0] will be created
  + resource "aws_nat_gateway" "this" {
      + allocation_id                      = (known after apply)
      + association_id                     = (known after apply)
      + auto_provision_zones               = (known after apply)
      + auto_scaling_ips                   = (known after apply)
      + availability_mode                  = (known after apply)
      + connectivity_type                  = "public"
      + id                                 = (known after apply)
      + network_interface_id               = (known after apply)
      + private_ip                         = (known after apply)
      + public_ip                          = (known after apply)
      + region                             = "eu-central-1"
      + regional_nat_gateway_address       = (known after apply)
      + regional_nat_gateway_auto_mode     = (known after apply)
      + route_table_id                     = (known after apply)
      + secondary_allocation_ids           = (known after apply)
      + secondary_private_ip_address_count = (known after apply)
      + secondary_private_ip_addresses     = (known after apply)
      + subnet_id                          = (known after apply)
      + tags                               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1a"
        }
      + tags_all                           = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Name"        = "staging-trip-planner-app-vpc-eu-central-1a"
        }
      + vpc_id                             = (known after apply)
    }

  # module.vpc.aws_nat_gateway.this[1] will be created
  + resource "aws_nat_gateway" "this" {
      + allocation_id    

...(truncated)

database

Click to expand
[command]/home/runner/work/_temp/fd95cdbb-0a93-4c1e-9853-59844971ce7b/terraform-bin show -no-color tfplan

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_cloudwatch_metric_alarm.rds_availability will be created
  + resource "aws_cloudwatch_metric_alarm" "rds_availability" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when DB has CPU utilization of 0% for 5 minutes- RDS is potentially down"
      + alarm_name                            = "staging-RDS-CPUUtilization-Down"
      + arn                                   = (known after apply)
      + comparison_operator                   = "LessThanThreshold"
      + dimensions                            = {
          + "DBInstanceIdentifier" = "staging-trip-planner-app-db"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "CPUUtilization"
      + namespace                             = "AWS/RDS"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 0
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.rds_free_storage will be created
  + resource "aws_cloudwatch_metric_alarm" "rds_free_storage" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when RDS free storage space is low"
      + alarm_name                            = "staging-RDS-Free-Storage-Low"
      + arn                                   = (known after apply)
      + comparison_operator                   = "LessThanThreshold"
      + dimensions                            = {
          + "DBInstanceIdentifier" = "staging-trip-planner-app-db"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 2
      + id                                    = (known after apply)
      + metric_name                           = "FreeStorageSpace"
      + namespace                             = "AWS/RDS"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 2000000000
      + treat_missing_data                    = "missing"
    }

  # aws_db_subnet_group.rds_subnet_group will be created
  + resource "aws_db_subnet_group" "rds_subnet_group" {
      + arn                     = (known after apply)
      + description             = "Managed by Terraform"
      + id                      = (known after apply)
      + name                    = "staging-trip-planner-app-rds-subnet-group"
      + name_prefix             = (known after apply)
      + region                  = "eu-central-1"
      + subnet_ids              = [
          + "subnet-placeholder1",
          + "subnet-placeholder2",
        ]
      + supported_network_types = (known after apply)
      + tags                    = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + vpc_id                  = (known after apply)
    }

  # aws_security_group.sg_rds will be created
  + resource "aws_security_group" "sg_rds" {
      + arn                    = (known after apply)
      + description            = "Allow ECS tasks access to database and internet"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "10.0.0.0/16",
                ]
              + 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      = []
              + from_port        = 5432
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 5432
                # (1 unchanged attribute hidden)
            },
        ]
      + name                   = "staging-trip-planner-app-rds-sg"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + region                 = "eu-central-1"
      + revoke_rules_on_delete = false
      + tags                   = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + vpc_id                 = "vpc-placeholder"
    }

  # module.rds_sns_alerts.aws_kms_key.sns_cmk will be created
  + resource "aws_kms_key" "sns_cmk" {
      + arn                                = (known after apply)
      + bypass_policy_lockout_safety_check = false
      + customer_master_key_spec           = "SYMMETRIC_DEFAULT"
      + description                        = "SNS CMK"
      + enable_key_rotation                = true
      + id                                 = (known after apply)
      + is_enabled                         = true
      + key_id                             = (known after apply)
      + key_usage                          = "ENCRYPT_DECRYPT"
      + multi_region                       = (known after apply)
      + policy                             = (known after apply)
      + region                             = "eu-central-1"
      + rotation_period_in_days            = (known after apply)
      + tags                               = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                           = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
    }

  # module.rds_sns_alerts.aws_sns_topic.alerts will be created
  + resource "aws_sns_topic" "alerts" {
      + arn                         = (known after apply)
      + beginning_archive_time      = (known after apply)
      + content_based_deduplication = false
      + fifo_throughput_scope       = (known after apply)
      + fifo_topic                  = false
      + id                          = (known after apply)
      + kms_master_key_id           = (known after apply)
      + name                        = "staging-trip-planner-app-staging-trip-planner-app-db-sns-topic"
      + name_prefix                 = (known after apply)
      + owner                       = (known after apply)
      + policy                      = (known after apply)
      + region                      = "eu-central-1"
      + signature_version           = (known after apply)
      + tags                        = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Service"     = "staging-trip-planner-app-db"
        }
      + tags_all                    = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
          + "Service"     = "staging-trip-planner-app-db"
        }
      + tracing_config              = (known after apply)
    }

  # module.rds_sns_alerts.aws_sns_topic_subscription.alerts_email will be created
  + resource "aws_sns_topic_subscription" "alerts_email" {
      + arn                             = (known after apply)
      + confirmation_timeout_in_minutes = 1
      + confirmation_was_authenticated  = (known after apply)
      + endpoint                        = "rmliantsoa@gmail.com"
      + 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
      + region                          = "eu-central-1"
      + topic_arn                       = (known after apply)
    }

  # module.db.module.db_instance.aws_db_instance.this[0] will be created
  + resource "aws_db_instance" "this" {
      + address                               = (known after apply)
      + allocated_storage                     = 20
      + allow_major_version_upgrade           = false
      + apply_immediately                     = false
      + arn                                   = (known after apply)
      + auto_minor_version_upgrade            = true
      + availability_zone                     = (known after apply)
      + backup_retention_period               = 0
      + backup_target                         = (known after apply)
      + backup_window                         = (known after apply)
      + ca_cert_identifier                    = (known after apply)
      + character_set_name                    = (known after apply)
      + copy_tags_to_snapshot                 = true
      + database_insights_mode                = (known after apply)
      + db_name                               = "stagingtripplannerappdbname"
      + db_subnet_group_name                  = "staging-trip-planner-app-rds-subnet-group"
      + dedicated_log_volume                  = false
      + delete_automated_backups              = true
      + deletion_protection                   = true
      + domain_fqdn                           = (known after apply)
      + endpoint                              = (known after apply)
      + engine                                = "postgres"
      + engine_lifecycle_support              = (known after apply)
      + engine_version                        = "15"
      + engine_version_actual                 = (known after apply)
      + final_snapshot_identifier             = (known after apply)
      + hosted_zone_id                        = (known after apply)
      + iam_database_authentication_enabled   = false
      + id                                    = (known after apply)
      + identifier                            = "staging-trip-planner-app-db"
      + identifier_prefix                     = (known after apply)
      + instance_class                        = "db.t3.micro"
      + iops                                  = (known after apply)
      + kms_key_id                            = (known after apply)
      + latest_restorable_time                = (known after apply)
      + license_model                         = (known after apply)
      + listener_endpoint                     = (known after apply)
      + maintenance_window                    = (known after apply)
      + manage_master_user_password           = true
      + master_user_secret                    = (known after apply)
      + master_user_secret_kms_key_id         = (known after apply)
      + max_allocated_storage                 = 0
      + monitoring_interval                   = 0
      + monitoring_role_arn                   = (known after apply)
      + multi_az                              = true
      + nchar_character_set_name              = (known after apply)
      + network_type                          = (known after apply)
      + option_group_name                     = (known after apply)
      + parameter_group_name                  = (known after apply)
      + password_wo                           = (write-only attribute)
      + performance_insights_enabled          = false
      + performance_insights_kms_key_id       = (known after apply)
      + performance_insights_retention_period = (known after apply)
      + port                                  = 5432
      + publicly_accessible                   = false
      + region                                = "eu-central-1"
      + replica_mode                          = (known after apply)
      + replicas                              = (known after apply)
      + resource_id                           = (known after apply)
      + skip_final_snapshot                   = false
      + snapshot_identifier                   = (known after apply)
      + status                                = (known after apply)
      + storage_encrypted                     = true
      + storage_throughput                    = (known after apply)
      + storage_type                          = (known after apply)
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "st

...(truncated)

backend

Click to expand
[command]/home/runner/work/_temp/2c59eb8a-9b43-44ba-8d6c-090fa26919c2/terraform-bin show -no-color tfplan

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_cloudwatch_metric_alarm.alb_5xx_errors will be created
  + resource "aws_cloudwatch_metric_alarm" "alb_5xx_errors" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "ALB is returning too many 5xx errors"
      + alarm_name                            = "alb-5xx-errors"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = (known after apply)
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "HTTPCode_Target_5XX_Count"
      + namespace                             = "AWS/ApplicationELB"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Sum"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 5
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.alb_high_latency will be created
  + resource "aws_cloudwatch_metric_alarm" "alb_high_latency" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "ALB latency above 2 seconds for 10 minutes"
      + alarm_name                            = "alb-high-latency"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = (known after apply)
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 2
      + id                                    = (known after apply)
      + metric_name                           = "TargetResponseTime"
      + namespace                             = "AWS/ApplicationELB"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 2
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.alb_unhealthy_hosts will be created
  + resource "aws_cloudwatch_metric_alarm" "alb_unhealthy_hosts" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "ALB target group has unhealthy hosts"
      + alarm_name                            = "staging-alb-unhealthy-hosts"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = (known after apply)
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "UnHealthyHostCount"
      + namespace                             = "AWS/ApplicationELB"
      + period                                = 60
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 0
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.ecs_cpu_high will be created
  + resource "aws_cloudwatch_metric_alarm" "ecs_cpu_high" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when ECS CPU utilization exceeds 90%"
      + alarm_name                            = "staging-trip-planner-app-ecs-service-CPUHigh"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = {
          + "ClusterName" = "staging-trip-planner-app-ecs-cluster"
          + "ServiceName" = "staging-trip-planner-app-ecs-service"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 2
      + id                                    = (known after apply)
      + metric_name                           = "CPUUtilization"
      + namespace                             = "AWS/ECS"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 90
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.ecs_memory_high will be created
  + resource "aws_cloudwatch_metric_alarm" "ecs_memory_high" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when ECS Memory utilization exceeds 90%"
      + alarm_name                            = "staging-trip-planner-app-ecs-service-MemoryHigh"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = {
          + "ClusterName" = "staging-trip-planner-app-ecs-cluster"
          + "ServiceName" = "staging-trip-planner-app-ecs-service"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 2
      + id                                    = (known after apply)
      + metric_name                           = "MemoryUtilization"
      + namespace                             = "AWS/ECS"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 90
      + treat_missing_data                    = "missing"
    }

  # aws_cloudwatch_metric_alarm.ecs_unhealthy_tasks will be created
  + resource "aws_cloudwatch_metric_alarm" "ecs_unhealthy_tasks" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when ECS service has unhealthy tasks"
      + alarm_name                            = "staging-trip-planner-app-ecs-service-UnhealthyTasks"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = {
          + "ClusterName" = "staging-trip-planner-app-ecs-cluster"
          + "ServiceName" = "staging-trip-planner-app-ecs-service"
        }
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "UnhealthyTaskCount"
      + namespace                             = "AWS/ECS"
      + period                                = 60
      + region                                = "eu-central-1"
      + statistic                             = "Maximum"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 0
      + treat_missing_data                    = "missing"
    }

  # aws_wafv2_web_acl.alb_waf will be created
  + resource "aws_wafv2_web_acl" "alb_waf" {
      + application_integration_url = (known after apply)
      + arn                         = (known after apply)
      + capacity                    = (known after apply)
      + description                 = "WAF for ALB"
      + id                          = (known after apply)
      + lock_token                  = (known after apply)
      + name                        = "staging-trip-planner-app-alb-waf"
      + name_prefix                 = (known after apply)
      + region                      = "eu-central-1"
      + scope                       = "REGIONAL"
      + tags                        = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                    = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }

      + default_action {
          + allow {
            }
        }

      + rule {
          + name     = "staging-trip-planner-app-BlockHydra"
          + priority = 103

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Hydra"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockHydra"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockMasscan"
          + priority = 104

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Masscan"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockMasscan"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockNikto"
          + priority = 100

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Nikto"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockNikto"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockSQLMap"
          + priority = 101

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
      

...(truncated)

frontend

Click to expand
[command]/home/runner/work/_temp/f71c94ce-0d3c-484d-94d3-497d1332ad64/terraform-bin show -no-color tfplan

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create
 <= read (data resources)

Terraform will perform the following actions:

  # aws_cloudwatch_metric_alarm.cloudfront_5xx will be created
  + resource "aws_cloudwatch_metric_alarm" "cloudfront_5xx" {
      + actions_enabled                       = true
      + alarm_actions                         = (known after apply)
      + alarm_description                     = "Alert when CloudFront 5xx errors spike"
      + alarm_name                            = "staging-trip-planner-app-CloudFront-5xx-Errors-High"
      + arn                                   = (known after apply)
      + comparison_operator                   = "GreaterThanThreshold"
      + dimensions                            = (known after apply)
      + evaluate_low_sample_count_percentiles = (known after apply)
      + evaluation_periods                    = 1
      + id                                    = (known after apply)
      + metric_name                           = "5xxErrorRate"
      + namespace                             = "AWS/CloudFront"
      + period                                = 300
      + region                                = "eu-central-1"
      + statistic                             = "Average"
      + tags                                  = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                              = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + threshold                             = 1
      + treat_missing_data                    = "missing"
    }

  # aws_wafv2_web_acl.cloudfront_waf will be created
  + resource "aws_wafv2_web_acl" "cloudfront_waf" {
      + application_integration_url = (known after apply)
      + arn                         = (known after apply)
      + capacity                    = (known after apply)
      + description                 = "WAF for CloudFront distribution of the Trip Planner app"
      + id                          = (known after apply)
      + lock_token                  = (known after apply)
      + name                        = "staging-trip-planner-app-cloudfront-waf"
      + name_prefix                 = (known after apply)
      + region                      = "us-east-1"
      + scope                       = "CLOUDFRONT"
      + tags                        = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                    = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }

      + default_action {
          + allow {
            }
        }

      + rule {
          + name     = "staging-trip-planner-app-BlockHydra"
          + priority = 13

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Hydra"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockHydra"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockMasscan"
          + priority = 14

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Masscan"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockMasscan"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockNikto"
          + priority = 10

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "Nikto"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockNikto"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockSQLMap"
          + priority = 11

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "SQLMap"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockSQLMap"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-BlockZAP"
          + priority = 12

          + action {
              + block {
                }
            }

          + statement {
              + byte_match_statement {
                  + positional_constraint = "CONTAINS"
                  + search_string         = "ZAP"

                  + field_to_match {
                      + single_header {
                          + name = "user-agent"
                        }
                    }

                  + text_transformation {
                      + priority = 0
                      + type     = "NONE"
                    }
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-BlockZAP"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-RateLimitPerIP"
          + priority = 16

          + action {
              + block {
                }
            }

          + statement {
              + rate_based_statement {
                  + aggregate_key_type    = "IP"
                  + evaluation_window_sec = 300
                  + limit                 = 1000
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "staging-trip-planner-app-rateLimit"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "staging-trip-planner-app-AWSManagedRulesCommonRuleSet"
          + priority = 1

          + override_action {
              + none {}
            }

          + statement {
              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesCommonRuleSet"
                  + vendor_name = "AWS"
                    # (1 unchanged attribute hidden)
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "managedRules"
              + sampled_requests_enabled   = true
            }
        }

      + visibility_config {
          + cloudwatch_metrics_enabled = true
          + metric_name                = "staging-trip-planner-app-CloudfrontWAF"
          + sampled_requests_enabled   = true
        }
    }

  # module.cloudfront.aws_cloudfront_distribution.cdn will be created
  + resource "aws_cloudfront_distribution" "cdn" {
      + aliases                         = [
          + "staging.epic-trip-planner.com",
        ]
      + arn                             = (known after apply)
      + caller_reference                = (known after apply)
      + continuous_deployment_policy_id = (known after apply)
      + default_root_object             = "index.html"
      + domain_name                     = (known after apply)
      + enabled                         = true
      + etag                            = (known after apply)
      + hosted_zone_id                  = (known after apply)
      + http_version                    = "http2"
      + id                              = (known after apply)
      + in_progress_validation_batches  = (known after apply)
      + is_ipv6_enabled                 = true
      + last_modified_time              = (known after apply)
      + logging_v1_enabled              = (known after apply)
      + price_class                     = "PriceClass_All"
      + retain_on_delete                = false
      + staging                         = false
      + status                          = (known after apply)
      + tags                            = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + tags_all                        = {
          + "App"         = "trip-planner-app"
          + "Environment" = "staging"
        }
      + trusted_key_groups              = (known after apply)
      + trusted_signers                 = (known after apply)
      + wait_for_deployment             = true
      + web_acl_id                      = (known after apply)

      + default_cache_behavior {
          + allowed_methods        = [
              + "GET",
              + "HEAD",
              + "OPTIONS",
            ]
          + cached_methods         = [
              + "GET",
              + "HEAD",
            ]
          + compress               = true
          + default_ttl            = 3600
          + max_ttl                = 86400
          + min_ttl                = 0
          + target_origin_id       = "staging-trip-planner-app-s3-static-web-files-bucket-origin"
          + trusted_key_groups     = (known after apply)
          + trusted_signers        = (known after apply)
          + viewer_protocol_policy = "redirect-to-https"

          + forwarded_values {
              + headers                 = (known after apply)
              + query_string            = false
              + query_string_cache_keys = (known after apply)

              + cookies {
                  + forward           = "none"
                  + whitelisted_names = (known after apply)
                }
            }

          + grpc_config (known after apply)

          + lambda_function_association {
              + event_type   = "viewer-request"
              + include_body = false
              + lambda_arn   = (known after apply)
            }
        }

      + ordered_cache_behavior {
          + allowed_methods        = [
              + "DELETE",
              + "GET",
              + "HEAD",
              + "OPTIONS",
              + "PATCH",
              + "POST",
              + "PUT",
            ]
          + cached_methods         = [
              + "GET",
              + "HEAD",
            ]
          + compress               = false
          + default_ttl            = 0
          + max_ttl                = 0
          + min_ttl                = 0
          + path_pattern           = "/api/*"
          + target_origin_id       = "staging-trip-planner-app-alb-origin"
          + viewer_protocol_policy = "redirect-to-https"

          + forwarded_values {
              + headers                 = (known after apply)
              + query_string            = true
              + query_string_cache_keys = (known after apply)

              + cookies {
                  + forward = "all"
                }
            }

          + grpc_config (known after apply)
        }
      + ordered_cache_behavior {
          + allowed_methods        = [
              + "DELETE",
              + "GET",
              + "HEAD",
              + "OPTIONS",
              + "PATCH",
              + "POST",
              + "PUT",
            ]
          + cached_methods         = [
              + "GET",
              + "HEAD",
            ]
          + compress               = false
          + default_ttl            = 0
          + max_ttl                = 0
          + min_ttl                = 0
          + path_pattern           = "/auth/*"
          + target_origin_id       = "staging-trip-planner-app-alb-origin"
          + viewer_protocol_pol

...(truncated)

🔐 Trivy Image Scan (Backend ECS Image)

Click to expand
lrasata/trip-planner-backend-app:1.1.0 (ubuntu 24.04)
=====================================================
Total: 0 (HIGH: 0, CRITICAL: 0)


Java (jar)
==========
Total: 7 (HIGH: 6, CRITICAL: 1)

┌─────────────────────────────────────────────────────────────┬────────────────┬──────────┬────────┬───────────────────┬────────────────────────────┬──────────────────────────────────────────────────────────────┐
│                           Library                           │ Vulnerability  │ Severity │ Status │ Installed Version │       Fixed Version        │                            Title                             │
├─────────────────────────────────────────────────────────────┼────────────────┼──────────┼────────┼───────────────────┼────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ io.netty:netty-codec-http2 (app.jar)                        │ CVE-2025-55163 │ HIGH     │ fixed  │ 4.1.119.Final     │ 4.2.4.Final, 4.1.124.Final │ netty: netty-codec-http2: Netty MadeYouReset HTTP/2 DDoS     │
│                                                             │                │          │        │                   │                            │ Vulnerability                                                │
│                                                             │                │          │        │                   │                            │ https://avd.aquasec.com/nvd/cve-2025-55163                   │
├─────────────────────────────────────────────────────────────┼────────────────┤          │        ├───────────────────┼────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ org.apache.tomcat.embed:tomcat-embed-core (app.jar)         │ CVE-2025-48988 │          │        │ 10.1.40           │ 11.0.8, 10.1.42, 9.0.106   │ tomcat: Apache Tomcat DoS in multipart upload                │
│                                                             │                │          │        │                   │                            │ https://avd.aquasec.com/nvd/cve-2025-48988                   │
│                                                             ├────────────────┤          │        │                   ├────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                                                             │ CVE-2025-48989 │          │        │                   │ 11.0.10, 10.1.44, 9.0.108  │ tomcat: http/2 "MadeYouReset" DoS attack through HTTP/2      │
│                                                             │                │          │        │                   │                            │ control frames                                               │
│                                                             │                │          │        │                   │                            │ https://avd.aquasec.com/nvd/cve-2025-48989                   │
│                                                             ├────────────────┤          │        │                   ├────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                                                             │ CVE-2025-55752 │          │        │                   │ 11.0.11, 10.1.45, 9.0.109  │ tomcat: org.apache.tomcat/tomcat-catalina: Apache Tomcat:    │
│                                                             │                │          │        │                   │                            │ Directory traversal via rewrite with possible RCE            │
│                                                             │                │          │        │                   │                            │ https://avd.aquasec.com/nvd/cve-2025-55752                   │
├─────────────────────────────────────────────────────────────┼────────────────┼──────────┤        ├───────────────────┼────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ org.springframework.security:spring-security-core (app.jar) │ CVE-2025-41232 │ CRITICAL │        │ 6.4.5             │ 6.4.6                      │ Spring-Security: Spring Security authorization bypass for    │
│                                                             │                │          │        │                   │                            │ method security annotations on private methods...            │
│                                                             │                │          │        │                   │                            │ https://avd.aquasec.com/nvd/cve-2025-41232                   │
│                                                             ├────────────────┼──────────┤        │                   ├────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                                                             │ CVE-2025-41248 │ HIGH     │        │                   │ 6.4.10, 6.5.4              │ org.springframework.security/spring-security-core: Spring    │
│                                                             │                │          │        │                   │                            │ Security authorization bypass                                │
│                                                             │                │          │        │                   │                            │ https://avd.aquasec.com/nvd/cve-2025-41248                   │
├─────────────────────────────────────────────────────────────┼────────────────┤          │        ├───────────────────┼────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ org.springframework:spring-core (app.jar)                   │ CVE-2025-41249 │          │        │ 6.2.6             │ 6.2.11                     │ org.springframework/spring-core: Spring Framework Annotation │
│                                                             │                │          │        │                   │                            │ Detection Vulnerability                                      │
│                                                             │                │          │        │                   │                            │ https://avd.aquasec.com/nvd/cve-2025-41249                   │
└─────────────────────────────────────────────────────────────┴────────────────┴──────────┴────────┴───────────────────┴────────────────────────────┴──────────────────────────────────────────────────────────────┘

@lrasata lrasata merged commit 0484fba into main Jan 7, 2026
7 checks passed
@lrasata lrasata deployed to ephemeral January 7, 2026 16:41 — with GitHub Actions Active
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

Comments