From be3e2796d4f5a5b68c44978661ba6d1040b9401e Mon Sep 17 00:00:00 2001 From: bocklag Date: Sun, 15 Dec 2024 16:12:34 +0000 Subject: [PATCH 1/3] feat(infra): rc-server(re-factoring terraform) --- apps/infra/rc/network/codedang/README.md | 3 + apps/infra/rc/network/codedang/cloudfront.tf | 114 ++++++++ .../infra/rc/network/codedang/codedang_api.tf | 29 ++ .../rc/network/codedang/codedang_iris.tf | 29 ++ .../codedang/codedang_service_admin.tf | 95 +++++++ .../codedang/codedang_service_client.tf | 125 +++++++++ .../network/codedang/codedang_service_iris.tf | 94 +++++++ .../container_definitions/admin_api.json | 74 ++++++ .../container_definitions/client_api.json | 94 +++++++ .../codedang/container_definitions/iris.json | 55 ++++ .../container_definitions/log_router.json | 18 ++ .../network/codedang/iam_ecs_instance_role.tf | 29 ++ .../codedang/iam_ecs_task_execution_role.tf | 29 ++ apps/infra/rc/network/codedang/main.tf | 54 ++++ .../rc/network/codedang/message_queue.tf | 61 +++++ .../modules/cluster_autoscaling/README.md | 53 ++++ .../cluster_autoscaling/autoscaling.tf | 85 ++++++ .../modules/cluster_autoscaling/cluster.tf | 14 + .../launch_template/user_data.sh | 5 + .../modules/cluster_autoscaling/main.tf | 26 ++ .../modules/cluster_autoscaling/outputs.tf | 3 + .../modules/cluster_autoscaling/variables.tf | 47 ++++ .../codedang/modules/loadbalancing/README.md | 46 ++++ .../modules/loadbalancing/loadbalancing.tf | 40 +++ .../codedang/modules/loadbalancing/main.tf | 26 ++ .../codedang/modules/loadbalancing/outputs.tf | 11 + .../modules/loadbalancing/variables.tf | 21 ++ .../modules/service_autoscaling/README.md | 52 ++++ .../appautoscaling_scale_down.tf | 39 +++ .../appautoscaling_scale_up.tf | 39 +++ .../service_autoscaling/ecs_service.tf | 28 ++ .../service_autoscaling/iam_task_role.tf | 32 +++ .../modules/service_autoscaling/main.tf | 44 ++++ .../modules/service_autoscaling/outputs.tf | 0 .../modules/service_autoscaling/variables.tf | 88 +++++++ apps/infra/rc/network/codedang/variables.tf | 23 ++ apps/infra/rc/network/network/README.md | 78 ++++++ apps/infra/rc/network/network/elastic_ip.tf | 15 ++ apps/infra/rc/network/network/main.tf | 20 ++ .../network/modules/security_group/main.tf | 12 + .../network/modules/security_group/outputs.tf | 3 + .../modules/security_group/security_group.tf | 21 ++ .../modules/security_group/variables.tf | 24 ++ .../rc/network/network/modules/subnet/main.tf | 13 + .../network/network/modules/subnet/outputs.tf | 3 + .../network/network/modules/subnet/subnet.tf | 17 ++ .../network/modules/subnet/variables.tf | 10 + .../rc/network/network/network_instance.tf | 41 +++ apps/infra/rc/network/network/outputs.tf | 50 ++++ .../rc/network/network/private_network.tf | 137 ++++++++++ .../rc/network/network/public_network.tf | 60 +++++ apps/infra/rc/network/network/route53.tf | 43 +++ .../rc/network/network/security_group.tf | 249 ++++++++++++++++++ apps/infra/rc/network/network/variables.tf | 27 ++ apps/infra/rc/network/network/vpc.tf | 40 +++ apps/infra/rc/network/storage/README.md | 63 +++++ apps/infra/rc/network/storage/database.tf | 30 +++ apps/infra/rc/network/storage/ecr.tf | 28 ++ apps/infra/rc/network/storage/main.tf | 37 +++ .../rc/network/storage/message_queue_aws.tf | 23 ++ apps/infra/rc/network/storage/outputs.tf | 58 ++++ apps/infra/rc/network/storage/redis.tf | 30 +++ apps/infra/rc/network/storage/s3_media.tf | 32 +++ .../rc/network/storage/s3_media_iam_user.tf | 23 ++ apps/infra/rc/network/storage/s3_testcase.tf | 30 +++ .../network/storage/s3_testcase_iam_user.tf | 24 ++ apps/infra/rc/network/storage/variables.tf | 33 +++ .../network/terraform-configuration/README.md | 37 +++ .../terraform-configuration/backend.tf | 21 ++ .../terraform-configuration/key_pair.tf | 11 + .../network/terraform-configuration/main.tf | 12 + .../modules/key_pair/key_pair.tf | 18 ++ .../modules/key_pair/main.tf | 13 + .../modules/key_pair/variables.tf | 11 + .../terraform-configuration/variables.tf | 7 + 75 files changed, 3029 insertions(+) create mode 100644 apps/infra/rc/network/codedang/README.md create mode 100644 apps/infra/rc/network/codedang/cloudfront.tf create mode 100644 apps/infra/rc/network/codedang/codedang_api.tf create mode 100644 apps/infra/rc/network/codedang/codedang_iris.tf create mode 100644 apps/infra/rc/network/codedang/codedang_service_admin.tf create mode 100644 apps/infra/rc/network/codedang/codedang_service_client.tf create mode 100644 apps/infra/rc/network/codedang/codedang_service_iris.tf create mode 100644 apps/infra/rc/network/codedang/container_definitions/admin_api.json create mode 100644 apps/infra/rc/network/codedang/container_definitions/client_api.json create mode 100644 apps/infra/rc/network/codedang/container_definitions/iris.json create mode 100644 apps/infra/rc/network/codedang/container_definitions/log_router.json create mode 100644 apps/infra/rc/network/codedang/iam_ecs_instance_role.tf create mode 100644 apps/infra/rc/network/codedang/iam_ecs_task_execution_role.tf create mode 100644 apps/infra/rc/network/codedang/main.tf create mode 100644 apps/infra/rc/network/codedang/message_queue.tf create mode 100644 apps/infra/rc/network/codedang/modules/cluster_autoscaling/README.md create mode 100644 apps/infra/rc/network/codedang/modules/cluster_autoscaling/autoscaling.tf create mode 100644 apps/infra/rc/network/codedang/modules/cluster_autoscaling/cluster.tf create mode 100644 apps/infra/rc/network/codedang/modules/cluster_autoscaling/launch_template/user_data.sh create mode 100644 apps/infra/rc/network/codedang/modules/cluster_autoscaling/main.tf create mode 100644 apps/infra/rc/network/codedang/modules/cluster_autoscaling/outputs.tf create mode 100644 apps/infra/rc/network/codedang/modules/cluster_autoscaling/variables.tf create mode 100644 apps/infra/rc/network/codedang/modules/loadbalancing/README.md create mode 100644 apps/infra/rc/network/codedang/modules/loadbalancing/loadbalancing.tf create mode 100644 apps/infra/rc/network/codedang/modules/loadbalancing/main.tf create mode 100644 apps/infra/rc/network/codedang/modules/loadbalancing/outputs.tf create mode 100644 apps/infra/rc/network/codedang/modules/loadbalancing/variables.tf create mode 100644 apps/infra/rc/network/codedang/modules/service_autoscaling/README.md create mode 100644 apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf create mode 100644 apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf create mode 100644 apps/infra/rc/network/codedang/modules/service_autoscaling/ecs_service.tf create mode 100644 apps/infra/rc/network/codedang/modules/service_autoscaling/iam_task_role.tf create mode 100644 apps/infra/rc/network/codedang/modules/service_autoscaling/main.tf create mode 100644 apps/infra/rc/network/codedang/modules/service_autoscaling/outputs.tf create mode 100644 apps/infra/rc/network/codedang/modules/service_autoscaling/variables.tf create mode 100644 apps/infra/rc/network/codedang/variables.tf create mode 100644 apps/infra/rc/network/network/README.md create mode 100644 apps/infra/rc/network/network/elastic_ip.tf create mode 100644 apps/infra/rc/network/network/main.tf create mode 100644 apps/infra/rc/network/network/modules/security_group/main.tf create mode 100644 apps/infra/rc/network/network/modules/security_group/outputs.tf create mode 100644 apps/infra/rc/network/network/modules/security_group/security_group.tf create mode 100644 apps/infra/rc/network/network/modules/security_group/variables.tf create mode 100644 apps/infra/rc/network/network/modules/subnet/main.tf create mode 100644 apps/infra/rc/network/network/modules/subnet/outputs.tf create mode 100644 apps/infra/rc/network/network/modules/subnet/subnet.tf create mode 100644 apps/infra/rc/network/network/modules/subnet/variables.tf create mode 100644 apps/infra/rc/network/network/network_instance.tf create mode 100644 apps/infra/rc/network/network/outputs.tf create mode 100644 apps/infra/rc/network/network/private_network.tf create mode 100644 apps/infra/rc/network/network/public_network.tf create mode 100644 apps/infra/rc/network/network/route53.tf create mode 100644 apps/infra/rc/network/network/security_group.tf create mode 100644 apps/infra/rc/network/network/variables.tf create mode 100644 apps/infra/rc/network/network/vpc.tf create mode 100644 apps/infra/rc/network/storage/README.md create mode 100644 apps/infra/rc/network/storage/database.tf create mode 100644 apps/infra/rc/network/storage/ecr.tf create mode 100644 apps/infra/rc/network/storage/main.tf create mode 100644 apps/infra/rc/network/storage/message_queue_aws.tf create mode 100644 apps/infra/rc/network/storage/outputs.tf create mode 100644 apps/infra/rc/network/storage/redis.tf create mode 100644 apps/infra/rc/network/storage/s3_media.tf create mode 100644 apps/infra/rc/network/storage/s3_media_iam_user.tf create mode 100644 apps/infra/rc/network/storage/s3_testcase.tf create mode 100644 apps/infra/rc/network/storage/s3_testcase_iam_user.tf create mode 100644 apps/infra/rc/network/storage/variables.tf create mode 100644 apps/infra/rc/network/terraform-configuration/README.md create mode 100644 apps/infra/rc/network/terraform-configuration/backend.tf create mode 100644 apps/infra/rc/network/terraform-configuration/key_pair.tf create mode 100644 apps/infra/rc/network/terraform-configuration/main.tf create mode 100644 apps/infra/rc/network/terraform-configuration/modules/key_pair/key_pair.tf create mode 100644 apps/infra/rc/network/terraform-configuration/modules/key_pair/main.tf create mode 100644 apps/infra/rc/network/terraform-configuration/modules/key_pair/variables.tf create mode 100644 apps/infra/rc/network/terraform-configuration/variables.tf diff --git a/apps/infra/rc/network/codedang/README.md b/apps/infra/rc/network/codedang/README.md new file mode 100644 index 0000000000..57ccaa5f4d --- /dev/null +++ b/apps/infra/rc/network/codedang/README.md @@ -0,0 +1,3 @@ +# Codedang + +Project for Codedang diff --git a/apps/infra/rc/network/codedang/cloudfront.tf b/apps/infra/rc/network/codedang/cloudfront.tf new file mode 100644 index 0000000000..3c8d5b00a4 --- /dev/null +++ b/apps/infra/rc/network/codedang/cloudfront.tf @@ -0,0 +1,114 @@ +data "aws_cloudfront_cache_policy" "disable" { + name = "Managed-CachingDisabled" +} + +data "aws_cloudfront_origin_request_policy" "allow_all" { + name = "Managed-AllViewer" +} + +data "aws_cloudfront_origin_request_policy" "exclude_host_header" { + name = "Managed-AllViewerExceptHostHeader" +} + +resource "aws_cloudfront_distribution" "codedang" { + origin { + domain_name = var.env == "production" ? "amplify.codedang.com" : "main.d11kq2upsmcpi9.amplifyapp.com" + origin_id = "frontend" # TODO: Add unique ID of Amplify + + custom_origin_config { + http_port = 80 + https_port = 443 + origin_protocol_policy = "https-only" + origin_ssl_protocols = ["TLSv1.2"] + } + } + + origin { + #domain_name = data.aws_lb.client_api.dns_name + #origin_id = data.aws_lb.client_api.id + domain_name = module.client_api_loadbalancer.aws_lb_dns_name + origin_id = module.client_api_loadbalancer.aws_lb_id + + custom_origin_config { + http_port = 80 + https_port = 443 + origin_protocol_policy = "http-only" # TODO: allow HTTPS only + origin_ssl_protocols = ["TLSv1.2"] + } + } + + origin { + #domain_name = data.aws_lb.admin_api.dns_name + #origin_id = data.aws_lb.admin_api.id + domain_name = module.admin_api_loadbalancer.aws_lb_dns_name + origin_id = module.admin_api_loadbalancer.aws_lb_id + + custom_origin_config { + http_port = 80 + https_port = 443 + origin_protocol_policy = "http-only" + origin_ssl_protocols = ["TLSv1.2"] + } + } + + enabled = true + comment = "Codedang-RC" + http_version = "http2and3" + + aliases = var.env == "rc" ? [] : ["codedang.com"] + + default_cache_behavior { + allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"] + cached_methods = ["GET", "HEAD", "OPTIONS"] + target_origin_id = "frontend" # TODO: do not hard-code origin_id + viewer_protocol_policy = "redirect-to-https" + cache_policy_id = data.aws_cloudfront_cache_policy.disable.id + origin_request_policy_id = data.aws_cloudfront_origin_request_policy.exclude_host_header.id + } + + ordered_cache_behavior { + path_pattern = "/api/*" + allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"] + cached_methods = ["GET", "HEAD", "OPTIONS"] + target_origin_id = module.client_api_loadbalancer.aws_lb_id + viewer_protocol_policy = "redirect-to-https" + cache_policy_id = data.aws_cloudfront_cache_policy.disable.id + origin_request_policy_id = data.aws_cloudfront_origin_request_policy.allow_all.id + } + + ordered_cache_behavior { + path_pattern = "/graphql" + allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"] + cached_methods = ["GET", "HEAD", "OPTIONS"] + target_origin_id = module.admin_api_loadbalancer.aws_lb_id + viewer_protocol_policy = "redirect-to-https" + cache_policy_id = data.aws_cloudfront_cache_policy.disable.id + origin_request_policy_id = data.aws_cloudfront_origin_request_policy.allow_all.id + } + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + + viewer_certificate { + cloudfront_default_certificate = var.env == "rc" ? true : false + acm_certificate_arn = var.env != "rc" ? local.network.route53_certificate_arn : null + ssl_support_method = var.env != "rc" ? "sni-only" : null + minimum_protocol_version = var.env != "rc" ? "TLSv1.2_2021" : null + } +} + +resource "aws_route53_record" "codedang" { + count = var.env == "production" ? 1 : 0 + name = "codedang.com" + type = "A" + zone_id = var.env == "rc" ? "" : local.network.route53_zone_id + + alias { + name = var.env == "rc" ? "" : aws_cloudfront_distribution.codedang.domain_name + zone_id = var.env == "rc" ? "" : aws_cloudfront_distribution.codedang.hosted_zone_id + evaluate_target_health = false + } +} diff --git a/apps/infra/rc/network/codedang/codedang_api.tf b/apps/infra/rc/network/codedang/codedang_api.tf new file mode 100644 index 0000000000..95d2be0032 --- /dev/null +++ b/apps/infra/rc/network/codedang/codedang_api.tf @@ -0,0 +1,29 @@ +module "codedang_api" { + source = "./modules/cluster_autoscaling" + + launch_template = { + name = "Codedang-LaunchTemplate-Api" + key_name = "codedang-ecs-api-instance" + iam_instance_profile_name = aws_iam_instance_profile.ecs_container_instance_profile.name + tags_name = "Codedang-ECS-API" + } + + autoscaling_group = { + name = "Codedang-AutoScalingGroup-Api" + max_size = 10 + desired_capacity = 1 + } + + autoscaling_policy = { + name = "Codedang-AutoScalingPolicy-Api" + target_value = 70 + } + + ecs_cluster_name = "Codedang-Api" + + ecs_capacity_provider_name = "codedang-api-capacity-provider" + + subnets = ["private_api1", "private_api2"] + + security_groups = ["sg_ecs_api"] +} diff --git a/apps/infra/rc/network/codedang/codedang_iris.tf b/apps/infra/rc/network/codedang/codedang_iris.tf new file mode 100644 index 0000000000..b26d00a2ba --- /dev/null +++ b/apps/infra/rc/network/codedang/codedang_iris.tf @@ -0,0 +1,29 @@ +module "codedang_iris" { + source = "./modules/cluster_autoscaling" + + launch_template = { + name = "Codedang-LaunchTemplate-Iris" + key_name = "codedang-ecs-iris-instance" + iam_instance_profile_name = aws_iam_instance_profile.ecs_container_instance_profile.name + tags_name = "Codedang-ECS-Iris" + } + + autoscaling_group = { + name = "Codedang-AutoScalingGroup-Iris" + max_size = 4 + desired_capacity = 1 + } + + autoscaling_policy = { + name = "Codedang-AutoScalingPolicy-Iris" + target_value = 80 + } + + ecs_cluster_name = "Codedang-Iris" + + ecs_capacity_provider_name = "codedang-capacity-provider-iris" + + subnets = ["private_iris1", "private_iris2"] + + security_groups = ["sg_ecs_iris"] +} diff --git a/apps/infra/rc/network/codedang/codedang_service_admin.tf b/apps/infra/rc/network/codedang/codedang_service_admin.tf new file mode 100644 index 0000000000..4481efa77c --- /dev/null +++ b/apps/infra/rc/network/codedang/codedang_service_admin.tf @@ -0,0 +1,95 @@ +data "aws_ecr_repository" "admin_api" { + name = "codedang-admin-api" +} + +module "admin_api_loadbalancer" { + source = "./modules/loadbalancing" + + lb = { + name = "Codedang-Admin-Api-LB" + subnets = ["public1", "public2"] + } + + lb_target_group = { + name = "Codedang-Admin-Api-TG" + port = 3000 + health_check_path = "/graphql" + } + + security_groups = ["sg_admin"] +} + +module "admin_api" { + source = "./modules/service_autoscaling" + + #TODO + task_definition = { + family = "Codedang-Admin-Api" + # memory = 950 + container_definitions = jsonencode([ + jsondecode(templatefile("container_definitions/admin_api.json", { + ecr_uri = data.aws_ecr_repository.admin_api.repository_url, + database_url = local.storage.db_url, + redis_host = local.storage.redis_host, + redis_port = var.redis_port, + jwt_secret = var.jwt_secret, + testcase_bucket_name = local.storage.s3_testcase_bucket.name, + testcase_access_key = local.storage.testcase_access_key, + testcase_secret_key = local.storage.testcase_secret_access_key, + media_bucket_name = local.storage.s3_media_bucket.name, + media_access_key = local.storage.media_access_key, + media_secret_key = local.storage.media_secret_access_key, + otel_exporter_otlp_endpoint_url = var.otel_exporter_otlp_endpoint_url, + loki_url = var.loki_url, + })), + jsondecode(file("container_definitions/log_router.json")) + ]) + execution_role_arn = aws_iam_role.ecs_task_execution_role.arn + } + + ecs_service = { + name = "Codedang-Admin-Api-Service" + cluster_arn = module.codedang_api.ecs_cluster.arn + desired_count = 1 + load_balancer = { + container_name = "Codedang-Admin-Api" + container_port = 3000 + target_group_arn = module.admin_api_loadbalancer.target_group_arn + } + } + + appautoscaling_target = { + min_capacity = 1 + max_capacity = 8 + resource_id = { + cluster_name = module.codedang_api.ecs_cluster.name + } + } + + scale_down = { + cloudwatch_metric_alarm = { + alarm_name = "Codedang-Admin-Api-Service-Scale-Down-Alert" + alarm_description = "This metric monitors task cpu utilization and scale down ecs service" + + datapoints_to_alarm = 10 + evaluation_periods = 10 + threshold = 50 + + dimensions = { + cluster_name = module.codedang_api.ecs_cluster.name + } + } + } + + scale_up = { + cloudwatch_metric_alarm = { + alarm_name = "Codedang-Admin-Api-Service-Scale-Up-Alert" + alarm_description = "This metric monitors task cpu utilization and scale up ecs service" + threshold = 120 + + dimensions = { + cluster_name = module.codedang_api.ecs_cluster.name + } + } + } +} diff --git a/apps/infra/rc/network/codedang/codedang_service_client.tf b/apps/infra/rc/network/codedang/codedang_service_client.tf new file mode 100644 index 0000000000..617da60565 --- /dev/null +++ b/apps/infra/rc/network/codedang/codedang_service_client.tf @@ -0,0 +1,125 @@ +data "aws_ecr_repository" "client_api" { + name = "codedang-client-api" +} + +module "client_api_loadbalancer" { + source = "./modules/loadbalancing" + + lb = { + name = "Codedang-Client-Api-LB" + subnets = ["public1", "public2"] + } + + lb_target_group = { + name = "Codedang-Client-Api-TG" + port = 4000 + health_check_path = "/api" + } + + security_groups = ["sg_client"] +} + +module "client_api" { + source = "./modules/service_autoscaling" + + #TODO + task_definition = { + family = "Codedang-Client-Api" + # memory = 950 + + container_definitions = jsonencode([ + jsondecode(templatefile("container_definitions/client_api.json", { + ecr_uri = data.aws_ecr_repository.client_api.repository_url, + database_url = local.storage.db_url, + redis_host = local.storage.redis_host, + redis_port = var.redis_port, + jwt_secret = var.jwt_secret, + rabbitmq_host = "${local.storage.mq_host_id}.mq.ap-northeast-2.amazonaws.com", + rabbitmq_port = var.rabbitmq_port, + rabbitmq_username = var.rabbitmq_username, + rabbitmq_password = local.storage.mq_password, + rabbitmq_vhost = rabbitmq_vhost.vh.name, + rabbitmq_api_url = local.storage.mq_api_url, + github_client_id = var.github_client_id, + github_client_secret = var.github_client_secret, + kakao_client_id = var.kakao_client_id, + kakao_client_secret = var.kakao_client_secret, + otel_exporter_otlp_endpoint_url = var.otel_exporter_otlp_endpoint_url, + loki_url = var.loki_url, + })), + jsondecode(file("container_definitions/log_router.json")) + ]) + + execution_role_arn = aws_iam_role.ecs_task_execution_role.arn + } + + task_role = { + iam_role = { + name = "Codedang-API-Task-Role" + description = null + } + + iam_policy = { + name = "Codedang-Api-Ses-Send-Email" + policy = jsonencode({ + Statement = [ + { + Action = [ + "ses:SendRawEmail", + "ses:SendEmail", + ] + Effect = "Allow" + Resource = "*" + }, + ] + Version = "2012-10-17" + }) + } + } + + ecs_service = { + name = "Codedang-Client-Api-Service" + cluster_arn = module.codedang_api.ecs_cluster.arn + desired_count = 2 + load_balancer = { + container_name = "Codedang-Client-Api" + container_port = 4000 + target_group_arn = module.client_api_loadbalancer.target_group_arn + } + } + + appautoscaling_target = { + min_capacity = 2 + max_capacity = 8 + resource_id = { + cluster_name = module.codedang_api.ecs_cluster.name + } + } + + scale_down = { + cloudwatch_metric_alarm = { + alarm_name = "Codedang-Client-Api-Service-Scale-Down-Alert" + alarm_description = "This metric monitors task cpu utilization and scale down ecs service" + + datapoints_to_alarm = 10 + evaluation_periods = 10 + threshold = 50 + + dimensions = { + cluster_name = module.codedang_api.ecs_cluster.name + } + } + } + + scale_up = { + cloudwatch_metric_alarm = { + alarm_name = "Codedang-Client-Api-Service-Scale-Up-Alert" + alarm_description = "This metric monitors task cpu utilization and scale up ecs service" + threshold = 120 + + dimensions = { + cluster_name = module.codedang_api.ecs_cluster.name + } + } + } +} diff --git a/apps/infra/rc/network/codedang/codedang_service_iris.tf b/apps/infra/rc/network/codedang/codedang_service_iris.tf new file mode 100644 index 0000000000..2152689305 --- /dev/null +++ b/apps/infra/rc/network/codedang/codedang_service_iris.tf @@ -0,0 +1,94 @@ +data "aws_ecr_repository" "iris" { + name = "codedang-iris" +} + +module "iris" { + source = "./modules/service_autoscaling" + + #TODO + task_definition = { + family = "Codedang-Iris-Api" + cpu = 512 + memory = 512 + + container_definitions = jsonencode([ + jsondecode(templatefile("container_definitions/iris.json", { + ecr_uri = data.aws_ecr_repository.iris.repository_url, + database_url = local.storage.db_url, + rabbitmq_host = "${local.storage.mq_host_id}.mq.ap-northeast-2.amazonaws.com", + rabbitmq_port = var.rabbitmq_port, + rabbitmq_username = var.rabbitmq_username, + rabbitmq_password = local.storage.mq_password, + rabbitmq_vhost = rabbitmq_vhost.vh.name, + otel_exporter_otlp_endpoint_url = var.otel_exporter_otlp_endpoint_url, + loki_url = var.loki_url, + })), + jsondecode(file("container_definitions/log_router.json")) + ]) + + execution_role_arn = aws_iam_role.ecs_task_execution_role.arn + } + + task_role = { + iam_role = { + name = "Codedang-Iris-Task-Role" + description = null + } + + iam_policy = { + name = "Codedang-Iris-Testcase-Access" + policy = jsonencode({ + Statement = [ + { + Action = "s3:GetObject" + Effect = "Allow" + Resource = ["${local.storage.s3_testcase_bucket.arn}/*"] + }, + ] + Version = "2012-10-17" + }) + } + } + + ecs_service = { + name = "Codedang-Iris-Service" + cluster_arn = module.codedang_iris.ecs_cluster.arn + desired_count = 2 + } + + appautoscaling_target = { + min_capacity = 2 + max_capacity = 8 + resource_id = { + cluster_name = module.codedang_iris.ecs_cluster.name + } + } + + scale_down = { + cloudwatch_metric_alarm = { + alarm_name = "Codedang-Iris-Service-Scale-Down-Alert" + alarm_description = "This metric monitors ec2 cpu utilization and scale down ecs service" + + datapoints_to_alarm = 15 + evaluation_periods = 15 + threshold = 45 + + dimensions = { + cluster_name = module.codedang_iris.ecs_cluster.name + } + } + } + + scale_up = { + cloudwatch_metric_alarm = { + alarm_name = "Codedang-Iris-Service-Scale-Up-Alert" + alarm_description = "This metric monitors ec2 cpu utilization and scale up ecs service" + statistic = "Average" + threshold = 60 + + dimensions = { + cluster_name = module.codedang_iris.ecs_cluster.name + } + } + } +} diff --git a/apps/infra/rc/network/codedang/container_definitions/admin_api.json b/apps/infra/rc/network/codedang/container_definitions/admin_api.json new file mode 100644 index 0000000000..22bb4c03bd --- /dev/null +++ b/apps/infra/rc/network/codedang/container_definitions/admin_api.json @@ -0,0 +1,74 @@ +{ + "name": "Codedang-Admin-Api", + "image": "${ecr_uri}", + "cpu": 600, + "memoryReservation": 512, + "essential": true, + "portMappings": [ + { + "containerPort": 3000 + } + ], + "environment": [ + { + "name": "DATABASE_URL", + "value": "${database_url}" + }, + { + "name": "REDIS_HOST", + "value": "${redis_host}" + }, + { + "name": "REDIS_PORT", + "value": "${redis_port}" + }, + { + "name": "JWT_SECRET", + "value": "${jwt_secret}" + }, + { + "name": "NODEMAILER_FROM", + "value": "Codedang " + }, + { + "name": "TESTCASE_BUCKET_NAME", + "value": "${testcase_bucket_name}" + }, + { + "name": "TESTCASE_ACCESS_KEY", + "value": "${testcase_access_key}" + }, + { + "name": "TESTCASE_SECRET_KEY", + "value": "${testcase_secret_key}" + }, + { + "name": "MEDIA_BUCKET_NAME", + "value": "${media_bucket_name}" + }, + { + "name": "MEDIA_ACCESS_KEY", + "value": "${media_access_key}" + }, + { + "name": "MEDIA_SECRET_KEY", + "value": "${media_secret_key}" + }, + { + "name": "OTEL_EXPORTER_OTLP_ENDPOINT_URL", + "value": "${otel_exporter_otlp_endpoint_url}" + } + ], + "logConfiguration": { + "logDriver": "awsfirelens", + "options": { + "LabelKeys": "container_name,ecs_task_definition,source,ecs_cluster", + "Labels": "{job=\"firelens\"}", + "LineFormat": "key_value", + "Name": "loki", + "RemoveKeys": "container_id,ecs_task_arn", + "Url": "${loki_url}" + }, + "secretOptions": [] + } +} diff --git a/apps/infra/rc/network/codedang/container_definitions/client_api.json b/apps/infra/rc/network/codedang/container_definitions/client_api.json new file mode 100644 index 0000000000..1fc90fd910 --- /dev/null +++ b/apps/infra/rc/network/codedang/container_definitions/client_api.json @@ -0,0 +1,94 @@ +{ + "name": "Codedang-Client-Api", + "image": "${ecr_uri}", + "cpu": 600, + "memoryReservation": 512, + "essential": true, + "portMappings": [ + { + "containerPort": 4000 + } + ], + "environment": [ + { + "name": "DATABASE_URL", + "value": "${database_url}" + }, + { + "name": "REDIS_HOST", + "value": "${redis_host}" + }, + { + "name": "REDIS_PORT", + "value": "${redis_port}" + }, + { + "name": "JWT_SECRET", + "value": "${jwt_secret}" + }, + { + "name": "NODEMAILER_FROM", + "value": "Codedang " + }, + { + "name": "RABBITMQ_SSL", + "value": "true" + }, + { + "name": "RABBITMQ_HOST", + "value": "${rabbitmq_host}" + }, + { + "name": "RABBITMQ_PORT", + "value": "${rabbitmq_port}" + }, + { + "name": "RABBITMQ_DEFAULT_USER", + "value": "${rabbitmq_username}" + }, + { + "name": "RABBITMQ_DEFAULT_PASS", + "value": "${rabbitmq_password}" + }, + { + "name": "RABBITMQ_DEFAULT_VHOST", + "value": "${rabbitmq_vhost}" + }, + { + "name": "RABBITMQ_API_URL", + "value": "${rabbitmq_api_url}" + }, + { + "name": "GITHUB_CLIENT_ID", + "value": "${github_client_id}" + }, + { + "name": "GITHUB_CLIENT_SECRET", + "value": "${github_client_secret}" + }, + { + "name": "KAKAO_CLIENT_ID", + "value": "${kakao_client_id}" + }, + { + "name": "KAKAO_CLIENT_SECRET", + "value": "${kakao_client_secret}" + }, + { + "name": "OTEL_EXPORTER_OTLP_ENDPOINT_URL", + "value": "${otel_exporter_otlp_endpoint_url}" + } + ], + "logConfiguration": { + "logDriver": "awsfirelens", + "options": { + "LabelKeys": "container_name,ecs_task_definition,source,ecs_cluster", + "Labels": "{job=\"firelens\"}", + "LineFormat": "key_value", + "Name": "loki", + "RemoveKeys": "container_id,ecs_task_arn", + "Url": "${loki_url}" + }, + "secretOptions": [] + } +} diff --git a/apps/infra/rc/network/codedang/container_definitions/iris.json b/apps/infra/rc/network/codedang/container_definitions/iris.json new file mode 100644 index 0000000000..f68d68317b --- /dev/null +++ b/apps/infra/rc/network/codedang/container_definitions/iris.json @@ -0,0 +1,55 @@ +{ + "name": "Codedang-Iris", + "image": "${ecr_uri}", + "essential": true, + "environment": [ + { + "name": "APP_ENV", + "value": "production" + }, + { + "name": "DATABASE_URL", + "value": "${database_url}" + }, + { + "name": "RABBITMQ_SSL", + "value": "true" + }, + { + "name": "RABBITMQ_HOST", + "value": "${rabbitmq_host}" + }, + { + "name": "RABBITMQ_PORT", + "value": "${rabbitmq_port}" + }, + { + "name": "RABBITMQ_DEFAULT_USER", + "value": "${rabbitmq_username}" + }, + { + "name": "RABBITMQ_DEFAULT_PASS", + "value": "${rabbitmq_password}" + }, + { + "name": "RABBITMQ_DEFAULT_VHOST", + "value": "${rabbitmq_vhost}" + }, + { + "name": "OTEL_EXPORTER_OTLP_ENDPOINT_URL", + "value": "${otel_exporter_otlp_endpoint_url}" + } + ], + "logConfiguration": { + "logDriver": "awsfirelens", + "options": { + "LabelKeys": "container_name,ecs_task_definition,source,ecs_cluster", + "Labels": "{job=\"firelens\"}", + "LineFormat": "key_value", + "Name": "loki", + "RemoveKeys": "container_id,ecs_task_arn", + "Url": "${loki_url}" + }, + "secretOptions": [] + } +} diff --git a/apps/infra/rc/network/codedang/container_definitions/log_router.json b/apps/infra/rc/network/codedang/container_definitions/log_router.json new file mode 100644 index 0000000000..6d6e7e66c7 --- /dev/null +++ b/apps/infra/rc/network/codedang/container_definitions/log_router.json @@ -0,0 +1,18 @@ +{ + "name": "log_router", + "image": "grafana/fluent-bit-plugin-loki:2.0.0-amd64", + "cpu": 0, + "memoryReservation": 50, + "portMappings": [], + "essential": true, + "environment": [], + "mountPoints": [], + "volumesFrom": [], + "user": "0", + "firelensConfiguration": { + "type": "fluentbit", + "options": { + "enable-ecs-log-metadata": "true" + } + } +} diff --git a/apps/infra/rc/network/codedang/iam_ecs_instance_role.tf b/apps/infra/rc/network/codedang/iam_ecs_instance_role.tf new file mode 100644 index 0000000000..b97ab4c3ce --- /dev/null +++ b/apps/infra/rc/network/codedang/iam_ecs_instance_role.tf @@ -0,0 +1,29 @@ +data "aws_iam_policy_document" "ec2_assume_role" { + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "ecs_container_instance_role" { + name = "Codedang-ECS-Container-Instance-Role" + assume_role_policy = data.aws_iam_policy_document.ec2_assume_role.json + + tags = { + Description = "ECS가 EC2 인스턴스를 등록할 수 있는 권한" + } +} + +resource "aws_iam_role_policy_attachment" "ecs_container_instance_role" { + role = aws_iam_role.ecs_container_instance_role.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" +} + +resource "aws_iam_instance_profile" "ecs_container_instance_profile" { + name = "Codedang-ECS-Container-Instance-Profile" + role = aws_iam_role.ecs_container_instance_role.name +} diff --git a/apps/infra/rc/network/codedang/iam_ecs_task_execution_role.tf b/apps/infra/rc/network/codedang/iam_ecs_task_execution_role.tf new file mode 100644 index 0000000000..d9dfedc644 --- /dev/null +++ b/apps/infra/rc/network/codedang/iam_ecs_task_execution_role.tf @@ -0,0 +1,29 @@ +data "aws_iam_policy_document" "task_assume_role" { + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ecs-tasks.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "ecs_task_execution_role" { + name = "Codedang-Api-Task-Execution-Role" + assume_role_policy = data.aws_iam_policy_document.task_assume_role.json + + tags = { + Description = "ECS agent가 작업을 실행하고 관리할 때 사용하는 권한" + } +} + +resource "aws_iam_role_policy_attachment" "ecs_task_execution_role" { + role = aws_iam_role.ecs_task_execution_role.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" +} + +resource "aws_iam_instance_profile" "ecs_task_execution_profile" { + name = "Codedang-ECS-Task-Execution-Profile" + role = aws_iam_role.ecs_task_execution_role.name +} diff --git a/apps/infra/rc/network/codedang/main.tf b/apps/infra/rc/network/codedang/main.tf new file mode 100644 index 0000000000..016106846f --- /dev/null +++ b/apps/infra/rc/network/codedang/main.tf @@ -0,0 +1,54 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + + rabbitmq = { + source = "cyrilgdn/rabbitmq" + version = "~>1.8" + } + } + + backend "s3" { + bucket = "codedang-tf-state" + key = "terraform/codedang.tfstate" + region = "ap-northeast-2" + encrypt = true + dynamodb_table = "terraform-state-lock" + } +} + +provider "aws" { + region = "ap-northeast-2" +} + +provider "rabbitmq" { + endpoint = local.storage.mq_api_url + username = var.rabbitmq_username + password = local.storage.mq_password +} + +data "terraform_remote_state" "network" { + backend = "s3" + config = { + bucket = "codedang-tf-state-rc" + key = "terraform/network.tfstate" + region = "ap-northeast-2" + } +} + +data "terraform_remote_state" "storage" { + backend = "s3" + config = { + bucket = "codedang-tf-state-rc" + key = "terraform/storage.tfstate" + region = "ap-northeast-2" + } +} + +locals { + network = data.terraform_remote_state.network.outputs + storage = data.terraform_remote_state.storage.outputs +} \ No newline at end of file diff --git a/apps/infra/rc/network/codedang/message_queue.tf b/apps/infra/rc/network/codedang/message_queue.tf new file mode 100644 index 0000000000..0a9ed314d8 --- /dev/null +++ b/apps/infra/rc/network/codedang/message_queue.tf @@ -0,0 +1,61 @@ +# provider.rabbitmq가 있어야 생성할 수 있는 자원들 +# mq_broker는 storage 프로젝트를 참조 + +resource "rabbitmq_vhost" "vh" { + name = "vh" +} + +resource "rabbitmq_permissions" "vh_perm" { + user = var.rabbitmq_username + vhost = rabbitmq_vhost.vh.name + + permissions { + configure = ".*" + write = ".*" + read = ".*" + } +} + +resource "rabbitmq_exchange" "exchange" { + name = "iris.e.direct.judge" + vhost = rabbitmq_permissions.vh_perm.vhost + + settings { + type = "direct" + durable = true + } +} + +resource "rabbitmq_queue" "result_queue" { + name = "iris.q.judge.result" + vhost = rabbitmq_permissions.vh_perm.vhost + + settings { + durable = true + } +} + +resource "rabbitmq_queue" "submission_queue" { + name = "client.q.judge.submission" + vhost = rabbitmq_permissions.vh_perm.vhost + + settings { + durable = true + } +} + +resource "rabbitmq_binding" "result_binding" { + source = rabbitmq_exchange.exchange.name + vhost = rabbitmq_vhost.vh.name + destination = rabbitmq_queue.result_queue.name + destination_type = "queue" + routing_key = "judge.result" +} + +resource "rabbitmq_binding" "submission_binding" { + source = rabbitmq_exchange.exchange.name + vhost = rabbitmq_vhost.vh.name + destination = rabbitmq_queue.submission_queue.name + destination_type = "queue" + routing_key = "judge.submission" +} diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/README.md b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/README.md new file mode 100644 index 0000000000..029998b2c4 --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/README.md @@ -0,0 +1,53 @@ +# Cluster Autoscaling + +Terraform module for Cluster Autoscaling. + +ECS Cluster 와 EC2 Autoscaling을 정의하는 모듈입니다. launch template을 이용하여 EC2 인스턴스를 정의하고 이를 `autoscaling_group`에 연결하여 CPU 사용률을 기준으로 자동으로 인스턴스를 스케일링합니다. 이와 함께 ECS 클러스터를 설정하고 `capacity_provider`를 연결하여 autoscaling을 구성합니다. + +## Requirements + +| Name | Version | +|------|---------| +| [aws](#requirement\_aws) | ~>5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~>5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_autoscaling_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource | +| [aws_autoscaling_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_policy) | resource | +| [aws_ecs_capacity_provider.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_capacity_provider) | resource | +| [aws_ecs_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster) | resource | +| [aws_ecs_cluster_capacity_providers.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster_capacity_providers) | resource | +| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | +| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_vpc.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [autoscaling\_group](#input\_autoscaling\_group) | The autoscaling group. e.g. {name='codedang-asg', max\_size=7} |
object({
name = string
max_size = number
})
| n/a | yes | +| [autoscaling\_policy](#input\_autoscaling\_policy) | The autoscaling policy with target tracking avg cpu utilization. e.g. {name='codedang-asp', target\_value=70} |
object({
name = string
target_value = number
})
| n/a | yes | +| [ecs\_capacity\_provider\_name](#input\_ecs\_capacity\_provider\_name) | The name of the ECS capacity provider. e.g. codedang-cp | `string` | n/a | yes | +| [ecs\_cluster\_name](#input\_ecs\_cluster\_name) | The name for the ECS cluster. e.g. codedang-cl | `string` | n/a | yes | +| [launch\_template](#input\_launch\_template) | The EC2 launch template configuration. e.g. {name='codedang-lt', key\_name='codedang-key', iam\_instance\_profile\_name='ecs-instance-profile', tags\_name='codedang-config'} |
object({
name = string
key_name = string

iam_instance_profile_name = string
tags_name = string
})
| n/a | yes | +| [security\_group](#input\_security\_group) | The security group for launch template network inteface. e.g. {name='codedang-sg', description='codedang allow you', ingress={description='from you', from\_port=11111, to\_port=22222, protocol='tcp'}} |
object({
name = string
description = string

ingress = object({
description = string
from_port = string
to_port = string
protocol = string

security_groups = optional(list(string))
cidr_blocks = optional(list(string))

ipv6_cidr_blocks = optional(list(string), [])
prefix_list_ids = optional(list(string), [])
self = optional(bool, false)
})
})
| n/a | yes | +| [subnets](#input\_subnets) | The map of subnets. e.g. {codedang\_subnet={cidr\_block='10.0.1.0/24', availability\_zone='ap-northeast-2a', tags\_name='codedang-sub'}} |
map(object({
cidr_block = string
availability_zone = string
tags_name = string
}))
| n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [ecs\_cluster](#output\_ecs\_cluster) | n/a | diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/autoscaling.tf b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/autoscaling.tf new file mode 100644 index 0000000000..820630f01a --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/autoscaling.tf @@ -0,0 +1,85 @@ +resource "aws_launch_template" "this" { + name = var.launch_template.name + image_id = "ami-05db432abf706dc01" + instance_type = "t3a.small" + key_name = var.launch_template.key_name + user_data = base64encode(templatefile("${path.module}/launch_template/user_data.sh", { + cluster_name = aws_ecs_cluster.this.name + })) + + iam_instance_profile { + name = var.launch_template.iam_instance_profile_name + } + + network_interfaces { + security_groups = [for name in var.security_groups : local.network.security_group_ids[name]] + } + + tag_specifications { + resource_type = "instance" + tags = { + Name = var.launch_template.tags_name + } + } +} + +resource "aws_autoscaling_group" "this" { + name = var.autoscaling_group.name + vpc_zone_identifier = [for name in var.subnets : local.network.subnet_ids[name]] + + desired_capacity = var.autoscaling_group.desired_capacity + min_size = 1 + max_size = var.autoscaling_group.max_size + + mixed_instances_policy { + launch_template { + launch_template_specification { + launch_template_id = aws_launch_template.this.id + version = aws_launch_template.this.latest_version + } + } + } + + lifecycle { + create_before_destroy = true + } + + tag { + key = "AmazonECSManaged" + value = "" + propagate_at_launch = true + } + + protect_from_scale_in = true + +} + +resource "aws_autoscaling_policy" "this" { + name = var.autoscaling_policy.name + autoscaling_group_name = aws_autoscaling_group.this.name + + policy_type = "TargetTrackingScaling" + estimated_instance_warmup = 300 + + target_tracking_configuration { + target_value = var.autoscaling_policy.target_value + predefined_metric_specification { + predefined_metric_type = "ASGAverageCPUUtilization" + } + } +} + +resource "aws_ecs_capacity_provider" "this" { + name = var.ecs_capacity_provider_name + auto_scaling_group_provider { + auto_scaling_group_arn = aws_autoscaling_group.this.arn + managed_termination_protection = "ENABLED" + + managed_scaling { + maximum_scaling_step_size = 5 + minimum_scaling_step_size = 1 + status = "ENABLED" + target_capacity = 100 + } + } +} diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/cluster.tf b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/cluster.tf new file mode 100644 index 0000000000..777967f6bf --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/cluster.tf @@ -0,0 +1,14 @@ +resource "aws_ecs_cluster" "this" { + name = var.ecs_cluster_name +} + +resource "aws_ecs_cluster_capacity_providers" "this" { + cluster_name = aws_ecs_cluster.this.name + capacity_providers = [aws_ecs_capacity_provider.this.name] + + default_capacity_provider_strategy { + capacity_provider = aws_ecs_capacity_provider.this.name + weight = 1 + base = 1 + } +} diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/launch_template/user_data.sh b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/launch_template/user_data.sh new file mode 100644 index 0000000000..297928cb9a --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/launch_template/user_data.sh @@ -0,0 +1,5 @@ +#!/bin/bash +echo ECS_CLUSTER="${cluster_name}" >> /etc/ecs/ecs.config +echo ECS_ENABLE_TASK_IAM_ROLE=true >> /etc/ecs/ecs.config +echo ECS_ENABLE_CONTAINER_METADATA=true >> /etc/ecs/ecs.config +echo ECS_CONTAINER_INSTANCE_PROPAGATE_TAGS_FROM=ec2_instance >> /etc/ecs/ecs.config diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/main.tf b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/main.tf new file mode 100644 index 0000000000..b49c9b2ff3 --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/main.tf @@ -0,0 +1,26 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } + +} + +provider "aws" { + region = "ap-northeast-2" +} + +data "terraform_remote_state" "network" { + backend = "s3" + config = { + bucket = "codedang-tf-state-rc" + key = "terraform/network.tfstate" + region = "ap-northeast-2" + } +} + +locals { + network = data.terraform_remote_state.network.outputs +} \ No newline at end of file diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/outputs.tf b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/outputs.tf new file mode 100644 index 0000000000..084942b48f --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/outputs.tf @@ -0,0 +1,3 @@ +output "ecs_cluster" { + value = aws_ecs_cluster.this +} diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/variables.tf b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/variables.tf new file mode 100644 index 0000000000..4c69a9691a --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/cluster_autoscaling/variables.tf @@ -0,0 +1,47 @@ +variable "launch_template" { + type = object({ + name = string + key_name = string + + iam_instance_profile_name = string + tags_name = string + }) + description = "The EC2 launch template configuration. e.g. {name='codedang-lt', key_name='codedang-key', iam_instance_profile_name='ecs-instance-profile', tags_name='codedang-config'}" +} + +variable "autoscaling_group" { + type = object({ + name = string + max_size = number + desired_capacity = number + }) + description = "The autoscaling group. e.g. {name='codedang-asg', max_size=7}" +} + +variable "autoscaling_policy" { + type = object({ + name = string + target_value = number + }) + description = "The autoscaling policy with target tracking avg cpu utilization. e.g. {name='codedang-asp', target_value=70}" +} + +variable "ecs_cluster_name" { + type = string + description = "The name for the ECS cluster. e.g. codedang-cl" +} + +variable "ecs_capacity_provider_name" { + type = string + description = "The name of the ECS capacity provider. e.g. codedang-cp" +} + +variable "subnets" { + type = list(string) + description = "List of subnet names. e.g. ['private_api1', 'private_api2']" +} + +variable "security_groups" { + type = list(string) + description = "List of SG names. e.g. ['sg_db', 'sg_redis']" +} \ No newline at end of file diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/README.md b/apps/infra/rc/network/codedang/modules/loadbalancing/README.md new file mode 100644 index 0000000000..4e8c7c9f80 --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/loadbalancing/README.md @@ -0,0 +1,46 @@ +# Loadbalancing + +Terraform module for Loadbalancing. + +어플리케이션 로드 밸런서를 정의하는 모듈입니다. instance 타입의 `aws_lb_target_group` health 체크를 통해 트래픽을 적절히 분배합니다. 80번 포트의 HTTP 요청을 타겟 그룹으로 포워딩합니다. + +## Requirements + +| Name | Version | +|------|---------| +| [aws](#requirement\_aws) | ~>5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~>5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_lb.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | +| [aws_lb_listener.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | +| [aws_lb_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | +| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_vpc.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [lb](#input\_lb) | The load balancer. e.g. {name='codedang-lb', subnets=['subnet-12345678']} |
object({
name = string
subnets = list(string)
})
| n/a | yes | +| [lb\_target\_group](#input\_lb\_target\_group) | The target group for load balancer. e.g. {name='codedang-tg', port=1234, health\_check\_path='/'} |
object({
name = string
port = number
health_check_path = string
})
| n/a | yes | +| [security\_group](#input\_security\_group) | The security group for load balancer. e.g. {name='codedang-sg'} |
object({
name = string
})
| n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [security\_group\_id](#output\_security\_group\_id) | n/a | +| [target\_group\_arn](#output\_target\_group\_arn) | n/a | diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/loadbalancing.tf b/apps/infra/rc/network/codedang/modules/loadbalancing/loadbalancing.tf new file mode 100644 index 0000000000..f33e441b42 --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/loadbalancing/loadbalancing.tf @@ -0,0 +1,40 @@ +resource "aws_lb" "this" { + name = var.lb.name + internal = false + load_balancer_type = "application" + security_groups = [for name in var.security_groups : local.network.security_group_ids[name]] + subnets = [for name in var.lb.subnets : local.network.subnet_ids[name]] + enable_http2 = true +} + +resource "aws_lb_target_group" "this" { + name = var.lb_target_group.name + target_type = "instance" + port = var.lb_target_group.port + protocol = "HTTP" + vpc_id = local.network.vpc_id + + health_check { + interval = 30 + path = var.lb_target_group.health_check_path + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-404" + } +} + +resource "aws_lb_listener" "this" { + load_balancer_arn = aws_lb.this.arn + port = "80" + protocol = "HTTP" + + default_action { + type = "forward" + forward { + target_group { + arn = aws_lb_target_group.this.arn + weight = 1 + } + } + } +} diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/main.tf b/apps/infra/rc/network/codedang/modules/loadbalancing/main.tf new file mode 100644 index 0000000000..b49c9b2ff3 --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/loadbalancing/main.tf @@ -0,0 +1,26 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } + +} + +provider "aws" { + region = "ap-northeast-2" +} + +data "terraform_remote_state" "network" { + backend = "s3" + config = { + bucket = "codedang-tf-state-rc" + key = "terraform/network.tfstate" + region = "ap-northeast-2" + } +} + +locals { + network = data.terraform_remote_state.network.outputs +} \ No newline at end of file diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/outputs.tf b/apps/infra/rc/network/codedang/modules/loadbalancing/outputs.tf new file mode 100644 index 0000000000..5abe64735a --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/loadbalancing/outputs.tf @@ -0,0 +1,11 @@ +output "target_group_arn" { + value = aws_lb_target_group.this.arn +} + +output "aws_lb_dns_name" { + value = aws_lb.this.dns_name +} + +output "aws_lb_id" { + value = aws_lb.this.id +} diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/variables.tf b/apps/infra/rc/network/codedang/modules/loadbalancing/variables.tf new file mode 100644 index 0000000000..f4d91f097b --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/loadbalancing/variables.tf @@ -0,0 +1,21 @@ +variable "lb" { + type = object({ + name = string + subnets = list(string) + }) + description = "The load balancer. e.g. {name='codedang-lb', subnets=['public1', 'public2]}" +} + +variable "lb_target_group" { + type = object({ + name = string + port = number + health_check_path = string + }) + description = "The target group for load balancer. e.g. {name='codedang-tg', port=1234, health_check_path='/'}" +} + +variable "security_groups" { + type = list(string) + description = "List of SG names. e.g. ['sg_db', 'sg_redis']" +} diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/README.md b/apps/infra/rc/network/codedang/modules/service_autoscaling/README.md new file mode 100644 index 0000000000..39919983c0 --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/service_autoscaling/README.md @@ -0,0 +1,52 @@ +# Service Autoscaling + +Terraform module for Service Autoscaling. + +ECS service 와 application autoscaling을 정의하는 모듈입니다. ECS의 task와 service를 설정하고, cloudwatch 및 appautoscaling 정책을 구성합니다. cloudwatch metric 알람이 cpu 사용률이 `threshold`를 기준으로 스케일링이 실행됩니다. + +## Requirements + +| Name | Version | +|------|---------| +| [aws](#requirement\_aws) | ~>5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~>5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_appautoscaling_policy.scale_down](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_policy) | resource | +| [aws_appautoscaling_policy.scale_up](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_policy) | resource | +| [aws_appautoscaling_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_target) | resource | +| [aws_cloudwatch_metric_alarm.scale_down](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource | +| [aws_cloudwatch_metric_alarm.scale_up](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource | +| [aws_ecs_service.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service) | resource | +| [aws_ecs_task_definition.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) | resource | +| [aws_iam_policy.task_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.task_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.task_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_policy_document.task_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [appautoscaling\_target](#input\_appautoscaling\_target) | The application autoscaling target. e.g. {min\_capacity=1, max\_capacity=7, resource\_id='service/codedang-cl/codedang-ecs'} |
object({
min_capacity = number
max_capacity = number
resource_id = object({
cluster_name = string
})
})
| n/a | yes | +| [ecs\_service](#input\_ecs\_service) | The ECS service configuration. e.g. {name='codedang-ecs', cluster\_arn='arn:aws:ecs:ap-northeast-2:12345678', desired\_count=1} |
object({
name = string
cluster_arn = string
desired_count = number

load_balancer = optional(object({
container_name = string
container_port = number
target_group_arn = string
}), null)
})
| n/a | yes | +| [scale\_down](#input\_scale\_down) | The settings for scaling down ECS tasks, including cloudwatch metric alarm. |
object({
cloudwatch_metric_alarm = object({
alarm_name = string
alarm_description = string

datapoints_to_alarm = number
evaluation_periods = number
threshold = number

dimensions = object({
cluster_name = string
})
})
})
| n/a | yes | +| [scale\_up](#input\_scale\_up) | The settings for scaling up ECS tasks, including cloudwatch metric alarm. |
object({
cloudwatch_metric_alarm = object({
alarm_name = string
alarm_description = string
threshold = number
statistic = optional(string, "Maximum")

dimensions = object({
cluster_name = string
})
})
})
| n/a | yes | +| [task\_definition](#input\_task\_definition) | The task definition. e.g. {family='codedang-fam', memory=512, container\_definitions=file('./codedang-cd.json'), execution\_role\_arn='arn:aws:iam:12345678'} |
object({
family = string
cpu = optional(number)
memory = number
container_definitions = any
execution_role_arn = string
})
| n/a | yes | +| [task\_role](#input\_task\_role) | The IAM role and policy information for ECS tasks, controlling permissions for containers executed within tasks. |
object({
iam_role = object({
name = string
description = string
})

iam_policy = object({
name = string
policy = string
})
})
| `null` | no | + +## Outputs + +No outputs. diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf b/apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf new file mode 100644 index 0000000000..92a4adc0e4 --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf @@ -0,0 +1,39 @@ +resource "aws_cloudwatch_metric_alarm" "scale_down" { + alarm_name = var.scale_down.cloudwatch_metric_alarm.alarm_name + alarm_description = var.scale_down.cloudwatch_metric_alarm.alarm_description + alarm_actions = [aws_appautoscaling_policy.scale_down.arn] + + comparison_operator = "LessThanThreshold" + datapoints_to_alarm = var.scale_down.cloudwatch_metric_alarm.datapoints_to_alarm + evaluation_periods = var.scale_down.cloudwatch_metric_alarm.evaluation_periods + metric_name = "CPUUtilization" + namespace = "AWS/ECS" + period = 60 + statistic = "Average" + threshold = var.scale_down.cloudwatch_metric_alarm.threshold + + dimensions = { + ClusterName = var.scale_down.cloudwatch_metric_alarm.dimensions.cluster_name + ServiceName = aws_ecs_service.this.name + } +} + +resource "aws_appautoscaling_policy" "scale_down" { + name = "scale-down" + policy_type = "StepScaling" + resource_id = aws_appautoscaling_target.this.resource_id + scalable_dimension = aws_appautoscaling_target.this.scalable_dimension + service_namespace = aws_appautoscaling_target.this.service_namespace + + step_scaling_policy_configuration { + adjustment_type = "ChangeInCapacity" + cooldown = 60 + metric_aggregation_type = "Average" + min_adjustment_magnitude = 0 + + step_adjustment { + metric_interval_upper_bound = -30 + scaling_adjustment = -1 + } + } +} diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf b/apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf new file mode 100644 index 0000000000..0f88cedafc --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf @@ -0,0 +1,39 @@ +resource "aws_cloudwatch_metric_alarm" "scale_up" { + alarm_name = var.scale_up.cloudwatch_metric_alarm.alarm_name + alarm_description = var.scale_up.cloudwatch_metric_alarm.alarm_description + alarm_actions = [aws_appautoscaling_policy.scale_up.arn] + + comparison_operator = "GreaterThanThreshold" + datapoints_to_alarm = 1 + evaluation_periods = 1 + metric_name = "CPUUtilization" + namespace = "AWS/ECS" + period = 60 + statistic = var.scale_up.cloudwatch_metric_alarm.statistic + threshold = var.scale_up.cloudwatch_metric_alarm.threshold + + dimensions = { + ClusterName = var.scale_up.cloudwatch_metric_alarm.dimensions.cluster_name + ServiceName = aws_ecs_service.this.name + } +} + +resource "aws_appautoscaling_policy" "scale_up" { + name = "scale-up" + policy_type = "StepScaling" + resource_id = aws_appautoscaling_target.this.resource_id + scalable_dimension = aws_appautoscaling_target.this.scalable_dimension + service_namespace = aws_appautoscaling_target.this.service_namespace + + step_scaling_policy_configuration { + adjustment_type = "ChangeInCapacity" + cooldown = 60 + metric_aggregation_type = "Average" + min_adjustment_magnitude = 0 + + step_adjustment { + metric_interval_lower_bound = 0 + scaling_adjustment = 1 + } + } +} diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/ecs_service.tf b/apps/infra/rc/network/codedang/modules/service_autoscaling/ecs_service.tf new file mode 100644 index 0000000000..8413186e0d --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/service_autoscaling/ecs_service.tf @@ -0,0 +1,28 @@ +resource "aws_ecs_task_definition" "this" { + family = var.task_definition.family + requires_compatibilities = ["EC2"] + network_mode = "bridge" + cpu = var.task_definition.cpu + memory = var.task_definition.memory + container_definitions = var.task_definition.container_definitions + execution_role_arn = var.task_definition.execution_role_arn + task_role_arn = try(aws_iam_role.task_role[0].arn, null) +} + +resource "aws_ecs_service" "this" { + name = var.ecs_service.name + cluster = var.ecs_service.cluster_arn + task_definition = aws_ecs_task_definition.this.family + desired_count = var.ecs_service.desired_count + launch_type = "EC2" + force_new_deployment = true + + dynamic "load_balancer" { + for_each = var.ecs_service.load_balancer != null ? [var.ecs_service.load_balancer] : [] + content { + container_name = load_balancer.value.container_name + container_port = load_balancer.value.container_port + target_group_arn = load_balancer.value.target_group_arn + } + } +} \ No newline at end of file diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/iam_task_role.tf b/apps/infra/rc/network/codedang/modules/service_autoscaling/iam_task_role.tf new file mode 100644 index 0000000000..a3d871b2ec --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/service_autoscaling/iam_task_role.tf @@ -0,0 +1,32 @@ +data "aws_iam_policy_document" "task_assume_role" { + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ecs-tasks.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "task_role" { + count = var.task_role != null ? 1 : 0 + + name = var.task_role.iam_role.name + description = var.task_role.iam_role.description + assume_role_policy = data.aws_iam_policy_document.task_assume_role.json +} + +resource "aws_iam_policy" "task_role" { + count = var.task_role != null ? 1 : 0 + + name = var.task_role.iam_policy.name + policy = var.task_role.iam_policy.policy +} + +resource "aws_iam_role_policy_attachment" "task_role" { + count = var.task_role != null ? 1 : 0 + + role = aws_iam_role.task_role[0].name + policy_arn = aws_iam_policy.task_role[0].arn +} diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/main.tf b/apps/infra/rc/network/codedang/modules/service_autoscaling/main.tf new file mode 100644 index 0000000000..1a0fa9790e --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/service_autoscaling/main.tf @@ -0,0 +1,44 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } + +} + +provider "aws" { + region = "ap-northeast-2" +} + +data "terraform_remote_state" "network" { + backend = "s3" + config = { + bucket = "codedang-tf-state-rc" + key = "terraform/network.tfstate" + region = "ap-northeast-2" + } +} + +data "terraform_remote_state" "storage" { + backend = "s3" + config = { + bucket = "codedang-tf-state-rc" + key = "terraform/storage.tfstate" + region = "ap-northeast-2" + } +} + +locals { + network = data.terraform_remote_state.network.outputs + storage = data.terraform_remote_state.storage.outputs +} + +resource "aws_appautoscaling_target" "this" { + min_capacity = var.appautoscaling_target.min_capacity + max_capacity = var.appautoscaling_target.max_capacity + resource_id = "service/${var.appautoscaling_target.resource_id.cluster_name}/${aws_ecs_service.this.name}" + scalable_dimension = "ecs:service:DesiredCount" + service_namespace = "ecs" +} diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/outputs.tf b/apps/infra/rc/network/codedang/modules/service_autoscaling/outputs.tf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/variables.tf b/apps/infra/rc/network/codedang/modules/service_autoscaling/variables.tf new file mode 100644 index 0000000000..77fc4051d6 --- /dev/null +++ b/apps/infra/rc/network/codedang/modules/service_autoscaling/variables.tf @@ -0,0 +1,88 @@ +variable "task_definition" { + type = object({ + family = string + cpu = optional(number) + memory = optional(number) + container_definitions = any + execution_role_arn = string + }) + description = "The task definition. e.g. {family='codedang-fam', memory=512, container_definitions=file('./codedang-cd.json'), execution_role_arn='arn:aws:iam:12345678'}" +} + +variable "task_role" { + type = object({ + iam_role = object({ + name = string + description = string + }) + + iam_policy = object({ + name = string + policy = string + }) + }) + default = null + description = "The IAM role and policy information for ECS tasks, controlling permissions for containers executed within tasks." +} + +variable "ecs_service" { + type = object({ + name = string + cluster_arn = string + desired_count = number + + load_balancer = optional(object({ + container_name = string + container_port = number + target_group_arn = string + }), null) + }) + description = "The ECS service configuration. e.g. {name='codedang-ecs', cluster_arn='arn:aws:ecs:ap-northeast-2:12345678', desired_count=1}" +} + +variable "appautoscaling_target" { + type = object({ + min_capacity = number + max_capacity = number + resource_id = object({ + cluster_name = string + }) + }) + description = "The application autoscaling target. e.g. {min_capacity=1, max_capacity=7, resource_id='service/codedang-cl/codedang-ecs'}" +} + + +variable "scale_down" { + type = object({ + cloudwatch_metric_alarm = object({ + alarm_name = string + alarm_description = string + + datapoints_to_alarm = number + evaluation_periods = number + threshold = number + + dimensions = object({ + cluster_name = string + }) + }) + }) + description = "The settings for scaling down ECS tasks, including cloudwatch metric alarm." +} + +variable "scale_up" { + type = object({ + cloudwatch_metric_alarm = object({ + alarm_name = string + alarm_description = string + threshold = number + statistic = optional(string, "Maximum") + + dimensions = object({ + cluster_name = string + }) + }) + }) + description = "The settings for scaling up ECS tasks, including cloudwatch metric alarm." +} + diff --git a/apps/infra/rc/network/codedang/variables.tf b/apps/infra/rc/network/codedang/variables.tf new file mode 100644 index 0000000000..5034325c96 --- /dev/null +++ b/apps/infra/rc/network/codedang/variables.tf @@ -0,0 +1,23 @@ +variable "rabbitmq_username" { + type = string + default = "skkuding" +} + +variable "rabbitmq_port" { + type = string + default = "5671" + sensitive = true +} + +# TODO: description 넣고 공통부분은 object로 처리 +variable "redis_port" { sensitive = true } +variable "jwt_secret" { sensitive = true } +variable "otel_exporter_otlp_endpoint_url" { sensitive = true } +variable "loki_url" { sensitive = true } + +variable "github_client_id" { sensitive = true } +variable "github_client_secret" { sensitive = true } +variable "kakao_client_id" { sensitive = true } +variable "kakao_client_secret" { sensitive = true } + +variable "env" { sensitive = true } diff --git a/apps/infra/rc/network/network/README.md b/apps/infra/rc/network/network/README.md new file mode 100644 index 0000000000..1e121f6f29 --- /dev/null +++ b/apps/infra/rc/network/network/README.md @@ -0,0 +1,78 @@ +# Network + +Project for Network + +코드당 인프라의 네트워크의 설정을 담은 프로젝트로 route53, cloudfront, subnet, nat 등을 관리합니다. +public network의 경우에는 본 프로젝트에서 관리하고, private network의 경우에는 각 리소스를 사용하는 서비스(프로젝트)에서 생성 및 사용하고, 본 프로젝트에서는 route table만 관리합니다. + + + +## Requirements + +| Name | Version | +|------|---------| +| [aws](#requirement\_aws) | ~> 5.52 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.52.0 | +| [aws.us-east-1](#provider\_aws.us-east-1) | 5.52.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_acm_certificate.codedang](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource | +| [aws_acm_certificate_validation.for_all_domains](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource | +| [aws_cloudfront_distribution.codedang](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource | +| [aws_eip.for_nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource | +| [aws_internet_gateway.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource | +| [aws_route53_record.certificate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | +| [aws_route53_record.codedang](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | +| [aws_route53_zone.codedang](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource | +| [aws_route_table.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource | +| [aws_route_table.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource | +| [aws_route_table_association.admin_api1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource | +| [aws_route_table_association.admin_api2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource | +| [aws_route_table_association.client_api1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource | +| [aws_route_table_association.client_api2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource | +| [aws_route_table_association.iris1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource | +| [aws_route_table_association.iris2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource | +| [aws_route_table_association.public_subnet1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource | +| [aws_route_table_association.public_subnet2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource | +| [aws_subnet.public_subnet1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_subnet.public_subnet2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_vpc.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource | +| [aws_cloudfront_cache_policy.disable](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_cache_policy) | data source | +| [aws_cloudfront_origin_request_policy.allow_all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_origin_request_policy) | data source | +| [aws_cloudfront_origin_request_policy.exclude_host_header](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_origin_request_policy) | data source | +| [aws_lb.admin_api](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/lb) | data source | +| [aws_lb.client_api](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/lb) | data source | +| [aws_subnet.private_admin_api1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | +| [aws_subnet.private_admin_api2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | +| [aws_subnet.private_client_api1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | +| [aws_subnet.private_client_api2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | +| [aws_subnet.private_iris1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | +| [aws_subnet.private_iris2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [private\_admin\_api1\_id](#input\_private\_admin\_api1\_id) | n/a | `any` | n/a | yes | +| [private\_admin\_api2\_id](#input\_private\_admin\_api2\_id) | n/a | `any` | n/a | yes | +| [private\_client\_api1\_id](#input\_private\_client\_api1\_id) | n/a | `any` | n/a | yes | +| [private\_client\_api2\_id](#input\_private\_client\_api2\_id) | n/a | `any` | n/a | yes | +| [private\_iris1\_id](#input\_private\_iris1\_id) | n/a | `any` | n/a | yes | +| [private\_iris2\_id](#input\_private\_iris2\_id) | n/a | `any` | n/a | yes | + +## Outputs + +No outputs. + diff --git a/apps/infra/rc/network/network/elastic_ip.tf b/apps/infra/rc/network/network/elastic_ip.tf new file mode 100644 index 0000000000..51b6ee766c --- /dev/null +++ b/apps/infra/rc/network/network/elastic_ip.tf @@ -0,0 +1,15 @@ +resource "aws_eip" "nat_instance" { + instance = aws_instance.nat_instance.id + + tags = { + Name = "Codedang-NAT-Instance" + } +} + +resource "aws_eip" "bastion_host" { + instance = aws_instance.bastion_host.id + + tags = { + Name = "Codedang-Bastion-Host" + } +} diff --git a/apps/infra/rc/network/network/main.tf b/apps/infra/rc/network/network/main.tf new file mode 100644 index 0000000000..74f2b8693d --- /dev/null +++ b/apps/infra/rc/network/network/main.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } + + backend "s3" { + bucket = "codedang-tf-state-rc" + key = "terraform/network.tfstate" + region = "ap-northeast-2" + encrypt = true + dynamodb_table = "terraform-state-lock" + } +} + +provider "aws" { + region = "ap-northeast-2" +} diff --git a/apps/infra/rc/network/network/modules/security_group/main.tf b/apps/infra/rc/network/network/modules/security_group/main.tf new file mode 100644 index 0000000000..bd8da140b1 --- /dev/null +++ b/apps/infra/rc/network/network/modules/security_group/main.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } +} + +provider "aws" { + region = "ap-northeast-2" +} diff --git a/apps/infra/rc/network/network/modules/security_group/outputs.tf b/apps/infra/rc/network/network/modules/security_group/outputs.tf new file mode 100644 index 0000000000..ef8d8e5b0b --- /dev/null +++ b/apps/infra/rc/network/network/modules/security_group/outputs.tf @@ -0,0 +1,3 @@ +output "security_group_ids" { + value = { for name, sg in aws_security_group.this : name => sg.id } +} diff --git a/apps/infra/rc/network/network/modules/security_group/security_group.tf b/apps/infra/rc/network/network/modules/security_group/security_group.tf new file mode 100644 index 0000000000..1b0364c1ef --- /dev/null +++ b/apps/infra/rc/network/network/modules/security_group/security_group.tf @@ -0,0 +1,21 @@ +resource "aws_security_group" "this" { + for_each = var.security_groups + + name = each.value.name + tags = { + Name = each.value.tags_name + } + + description = each.value.description + vpc_id = each.value.vpc_id + + ingress = each.value.ingress + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } +} diff --git a/apps/infra/rc/network/network/modules/security_group/variables.tf b/apps/infra/rc/network/network/modules/security_group/variables.tf new file mode 100644 index 0000000000..fdb7f176f0 --- /dev/null +++ b/apps/infra/rc/network/network/modules/security_group/variables.tf @@ -0,0 +1,24 @@ +variable "security_groups" { + type = map(object({ + name = string + tags_name = string + description = string + vpc_id = string + + + ingress = list(object({ + description = string + from_port = string + to_port = string + protocol = string + + security_groups = optional(list(string)) + cidr_blocks = optional(list(string)) + + ipv6_cidr_blocks = optional(list(string), []) + prefix_list_ids = optional(list(string), []) + self = optional(bool, false) + })) + })) + description = "The security group for launch template network inteface. e.g. {name='codedang-sg', description='codedang allow you', tags_name='codedang-sg', ingress={description='from you', from_port=11111, to_port=22222, protocol='tcp'}}" +} diff --git a/apps/infra/rc/network/network/modules/subnet/main.tf b/apps/infra/rc/network/network/modules/subnet/main.tf new file mode 100644 index 0000000000..5e936f55e6 --- /dev/null +++ b/apps/infra/rc/network/network/modules/subnet/main.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } + +} + +provider "aws" { + region = "ap-northeast-2" +} diff --git a/apps/infra/rc/network/network/modules/subnet/outputs.tf b/apps/infra/rc/network/network/modules/subnet/outputs.tf new file mode 100644 index 0000000000..09ff449104 --- /dev/null +++ b/apps/infra/rc/network/network/modules/subnet/outputs.tf @@ -0,0 +1,3 @@ +output "subnet_ids" { + value = { for key, subnet in aws_subnet.this : key => subnet.id } +} diff --git a/apps/infra/rc/network/network/modules/subnet/subnet.tf b/apps/infra/rc/network/network/modules/subnet/subnet.tf new file mode 100644 index 0000000000..451c035bc8 --- /dev/null +++ b/apps/infra/rc/network/network/modules/subnet/subnet.tf @@ -0,0 +1,17 @@ +resource "aws_subnet" "this" { + for_each = var.subnets + vpc_id = each.value.vpc_id + cidr_block = each.value.cidr_block + availability_zone = each.value.availability_zone + + tags = { + Name = each.value.tags_name + } +} + +resource "aws_route_table_association" "this" { + for_each = var.subnets + + subnet_id = aws_subnet.this[each.key].id + route_table_id = each.value.route_table_id +} diff --git a/apps/infra/rc/network/network/modules/subnet/variables.tf b/apps/infra/rc/network/network/modules/subnet/variables.tf new file mode 100644 index 0000000000..3675c2735b --- /dev/null +++ b/apps/infra/rc/network/network/modules/subnet/variables.tf @@ -0,0 +1,10 @@ +variable "subnets" { + type = map(object({ + vpc_id = string + cidr_block = string + availability_zone = string + tags_name = string + route_table_id = string + })) + description = "The map of subnets. e.g. {codedang_subnet={cidr_block='10.0.1.0/24', availability_zone='ap-northeast-2a', tags_name='codedang-sub', subnet_type='private'}}" +} diff --git a/apps/infra/rc/network/network/network_instance.tf b/apps/infra/rc/network/network/network_instance.tf new file mode 100644 index 0000000000..cd186fbfb6 --- /dev/null +++ b/apps/infra/rc/network/network/network_instance.tf @@ -0,0 +1,41 @@ +resource "aws_instance" "nat_instance" { + ami = "ami-08271b263d7b4ae11" + instance_type = "t4g.micro" + subnet_id = module.public_api_subnets.subnet_ids["public_nat"] + vpc_security_group_ids = [module.nat_security_groups.security_group_ids["sg_nat_instance"]] + source_dest_check = false + key_name = "nat-instance" + + user_data = <<-EOF + #!/bin/bash + # 1. iptables 서비스 활성화 + sudo yum install -y iptables-services + sudo systemctl enable iptables + sudo systemctl start iptables + + # 2. IP 포워딩 활성화 및 영구 설정 + echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/custom-ip-forwarding.conf + sudo sysctl -p /etc/sysctl.d/custom-ip-forwarding.conf + + # 3. iptables NAT 설정 + # t4g 시리즈는 Nitro 기반이므로 ens5 사용 (주의!) + sudo iptables -t nat -A POSTROUTING -o ens5 -j MASQUERADE + sudo iptables -F FORWARD + sudo service iptables save + EOF + + tags = { + Name = "NAT-Instance" + } +} + +resource "aws_instance" "bastion_host" { + ami = "ami-0c68ab5091e5f073a" + instance_type = "t4g.nano" + subnet_id = module.public_api_subnets.subnet_ids["public_bastion"] + vpc_security_group_ids = [module.ssh_security_groups.security_group_ids["sg_ssh"]] + key_name = "bastion-host" + tags = { + Name = "Bastion-Host" + } +} diff --git a/apps/infra/rc/network/network/outputs.tf b/apps/infra/rc/network/network/outputs.tf new file mode 100644 index 0000000000..0bc55424d6 --- /dev/null +++ b/apps/infra/rc/network/network/outputs.tf @@ -0,0 +1,50 @@ +output "vpc_id" { + value = aws_vpc.main.id + sensitive = true +} + +output "private_route_table_id" { + value = aws_route_table.private.id + sensitive = true +} + +output "public_ip" { + value = aws_eip.nat_instance.public_ip + sensitive = true +} + +output "mq_subnet_id" { + value = aws_subnet.private_mq.id + sensitive = true +} + +output "subnet_ids" { + value = merge( + #Private + module.private_api_subnets.subnet_ids, + module.private_iris_subnets.subnet_ids, + module.private_admin_api_subnets.subnet_ids, + module.private_redis_subnets.subnet_ids, + module.private_db_subnets.subnet_ids, + #Public + module.public_api_subnets.subnet_ids + ) +} + +output "security_group_ids" { + value = merge( + module.storage_security_groups.security_group_ids, + module.lb_security_groups.security_group_ids, + module.ssh_security_groups.security_group_ids, + module.app_security_groups.security_group_ids, + module.nat_security_groups.security_group_ids + ) +} + +output "route53_zone_id" { + value = length(aws_route53_zone.codedang) > 0 ? aws_route53_zone.codedang[0].zone_id : null +} + +output "route53_certificate_arn" { + value = length(aws_acm_certificate_validation.for_all_domains) > 0 ? aws_acm_certificate_validation.for_all_domains[0].certificate_arn : null +} \ No newline at end of file diff --git a/apps/infra/rc/network/network/private_network.tf b/apps/infra/rc/network/network/private_network.tf new file mode 100644 index 0000000000..385ad3eb7b --- /dev/null +++ b/apps/infra/rc/network/network/private_network.tf @@ -0,0 +1,137 @@ +resource "aws_route_table" "private" { + vpc_id = aws_vpc.main.id + + route { + cidr_block = "0.0.0.0/0" + network_interface_id = aws_instance.nat_instance.primary_network_interface_id + } + + tags = { + Name = "Codedang-Private-RT" + } +} + +module "private_api_subnets" { + source = "./modules/subnet" + + subnets = { + private_api1 = { + cidr_block = "10.0.1.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2a" + tags_name = "Codedang-Api-Subnet1" + route_table_id = aws_route_table.private.id + } + private_api2 = { + cidr_block = "10.0.2.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2c" + tags_name = "Codedang-Api-Subnet2" + route_table_id = aws_route_table.private.id + } + } +} + +module "private_iris_subnets" { + source = "./modules/subnet" + + subnets = { + private_iris1 = { + cidr_block = "10.0.41.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2a" + tags_name = "Codedang-Iris-Subnet1" + route_table_id = aws_route_table.private.id + } + private_iris2 = { + cidr_block = "10.0.42.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2c" + tags_name = "Codedang-Iris-Subnet2" + route_table_id = aws_route_table.private.id + } + } +} + +module "private_admin_api_subnets" { + source = "./modules/subnet" + + subnets = { + private_admin_api1 = { + cidr_block = "10.0.3.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2a" + tags_name = "Codedang-Admin-Api-Subnet1" + route_table_id = aws_route_table.private.id + } + private_admin_api2 = { + cidr_block = "10.0.4.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2c" + tags_name = "Codedang-Admin-Api-Subnet2" + route_table_id = aws_route_table.private.id + } + } +} + +module "private_redis_subnets" { + source = "./modules/subnet" + + subnets = { + private_redis1 = { + cidr_block = "10.0.31.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2a" + tags_name = "Codedang_Redis-Subnet1" + route_table_id = aws_route_table.private.id + } + private_redis2 = { + cidr_block = "10.0.32.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2b" + tags_name = "Codedang_Redis-Subnet2" + route_table_id = aws_route_table.private.id + } + } +} + +module "private_db_subnets" { + source = "./modules/subnet" + + subnets = { + private_db1 = { + cidr_block = "10.0.11.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2a" + tags_name = "Codedang-DB-Subnet1" + route_table_id = aws_route_table.private.id + } + private_db2 = { + cidr_block = "10.0.12.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2b" + tags_name = "Codedang-DB-Subnet2" + route_table_id = aws_route_table.private.id + } + private_db3 = { + cidr_block = "10.0.13.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2c" + tags_name = "Codedang-DB-Subnet3" + route_table_id = aws_route_table.private.id + } + } +} + +# 알림: Route Table 연결이 불필요해 모듈로 생성하지 않음. +# 일관성을 위해 Network 프로젝트에 두었으나, 차후 하이브리드 클라우드 +# 전환 시 유연하게 대처할 것... +resource "aws_subnet" "private_mq" { + vpc_id = aws_vpc.main.id + cidr_block = "10.0.20.0/24" + availability_zone = "ap-northeast-2a" + + tags = { + Name = "Codedang-MQ-Subnet1" + } +} \ No newline at end of file diff --git a/apps/infra/rc/network/network/public_network.tf b/apps/infra/rc/network/network/public_network.tf new file mode 100644 index 0000000000..ad5eb10cb7 --- /dev/null +++ b/apps/infra/rc/network/network/public_network.tf @@ -0,0 +1,60 @@ +resource "aws_internet_gateway" "main" { + vpc_id = aws_vpc.main.id + + tags = { + Name = "Codedang-InternetFacing" + } +} + +resource "aws_route_table" "public" { + vpc_id = aws_vpc.main.id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.main.id + } + + route { + ipv6_cidr_block = "::/0" + gateway_id = aws_internet_gateway.main.id + } + + tags = { + Name = "Codedang-Public-RT" + } +} + +module "public_api_subnets" { + source = "./modules/subnet" + + subnets = { + public1 = { + cidr_block = "10.0.90.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2a" + tags_name = "Codedang-Public-Nat-Subnet1" + route_table_id = aws_route_table.public.id + } + public2 = { + cidr_block = "10.0.91.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2c" + tags_name = "Codedang-Public-Nat-Subnet2" + route_table_id = aws_route_table.public.id + } + public_nat = { + cidr_block = "10.0.93.0/24" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2a" + tags_name = "Codedang-Nat-Instance" + route_table_id = aws_route_table.public.id + } + public_bastion = { + cidr_block = "10.0.255.32/28" + vpc_id = aws_vpc.main.id + availability_zone = "ap-northeast-2a" + tags_name = "Codedang-Basstion-Host" + route_table_id = aws_route_table.public.id + } + } +} diff --git a/apps/infra/rc/network/network/route53.tf b/apps/infra/rc/network/network/route53.tf new file mode 100644 index 0000000000..df56c415e2 --- /dev/null +++ b/apps/infra/rc/network/network/route53.tf @@ -0,0 +1,43 @@ +provider "aws" { + alias = "us_east_1" + region = "us-east-1" +} + +resource "aws_route53_zone" "codedang" { + count = var.env == "production" ? 1 : 0 + name = "codedang.com" +} + +resource "aws_acm_certificate" "codedang" { + count = var.env == "production" ? 1 : 0 + domain_name = "codedang.com" + validation_method = "DNS" + provider = aws.us_east_1 +} + +resource "aws_route53_record" "certificate" { + for_each = var.env == "production" ? { + for dvo in aws_acm_certificate.codedang[0].domain_validation_options : dvo.domain_name => { + name = dvo.resource_record_name + zone_id = aws_route53_zone.codedang[0].zone_id + type = dvo.resource_record_type + value = dvo.resource_record_value + } + } : {} + + allow_overwrite = true + name = each.value.name + records = [each.value.value] + ttl = 60 + type = each.value.type + zone_id = each.value.zone_id +} + +resource "aws_acm_certificate_validation" "for_all_domains" { + count = var.env == "production" ? 1 : 0 + provider = aws.us_east_1 + certificate_arn = aws_acm_certificate.codedang[0].arn + validation_record_fqdns = [ + for record in aws_route53_record.certificate : record.fqdn + ] +} diff --git a/apps/infra/rc/network/network/security_group.tf b/apps/infra/rc/network/network/security_group.tf new file mode 100644 index 0000000000..3241a9befd --- /dev/null +++ b/apps/infra/rc/network/network/security_group.tf @@ -0,0 +1,249 @@ +module "storage_security_groups" { + source = "./modules/security_group" + + security_groups = { + sg_db = { + name = "Codedang-SG-DB" + tags_name = "Codedang-SG-DB" + description = "Allow DB inbound traffic" + vpc_id = aws_vpc.main.id + ingress = [ + { + description = "PostgreSQL" + from_port = var.postgres_port + to_port = var.postgres_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + }, + { + description = "HTTPS" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ] + } + sg_redis = { + name = "Codedang-SG-Redis" + tags_name = "Codedang-SG-Redis" + description = "Allow Redis inbound traffic" + vpc_id = aws_vpc.main.id + ingress = [ + { + description = "Redis" + from_port = var.redis_port + to_port = var.redis_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + }, + { + description = "HTTPS" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ] + } + } +} + +module "lb_security_groups" { + source = "./modules/security_group" + + security_groups = { + sg_admin = { + name = "Codedang-SG-LB-Admin" + tags_name = "Codedang-SG-LB-Admin" + description = "Allow WEB inbound traffic" + vpc_id = aws_vpc.main.id + ingress = [ + { + description = "HTTP" + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + }, + { + description = "HTTPS" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ] + } + sg_client = { + name = "Codedang-SG-LB-Client" + tags_name = "Codedang-SG-LB-Client" + description = "Allow WEB inbound traffic" + vpc_id = aws_vpc.main.id + ingress = [ + { + description = "HTTP" + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + }, + { + description = "HTTPS" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ] + } + } +} + +module "ssh_security_groups" { + source = "./modules/security_group" + + security_groups = { + sg_ssh = { + name = "Codedang-AllowSSH" + tags_name = "Codedang-AllowSSH" + description = "Allow SSH for Codedang debug" + vpc_id = aws_vpc.main.id + ingress = [ + { + description = "SSH" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ] + } + } +} + +module "app_security_groups" { + source = "./modules/security_group" + #depends_on = [module.storage_security_groups] + + security_groups = { + sg_ecs_api = { + name = "Codedang-SG-ECS-Api" + tags_name = "Codedang-SG-ECS-Api" + description = "Allow ECS inbound traffic" + vpc_id = aws_vpc.main.id + ingress = [ + { + description = "SSH" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + }, + { + description = "From ALB" + from_port = 32768 + to_port = 65535 + protocol = "tcp" + + security_groups = [ + module.lb_security_groups.security_group_ids["sg_admin"], + module.lb_security_groups.security_group_ids["sg_client"] + ] + } + ] + } + sg_ecs_iris = { + name = "Codedang-SG-Iris" + tags_name = "Codedang-SG-Iris" + description = "Allow Message Queue inbound traffic" + vpc_id = aws_vpc.main.id + ingress = [ + { + description = "SSH" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + }, + { + description = "Iris" + from_port = var.rabbitmq_port + to_port = var.rabbitmq_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ] + } + } +} + +module "nat_security_groups" { + source = "./modules/security_group" + #depends_on = [module.app_security_groups, module.ssh_security_groups] + + security_groups = { + sg_nat_instance = { + name = "Codedang-SG-NAT-Instance" + tags_name = "Codedang-SG-NAT-Instance" + description = "Allow Fluent-bit and Other NAT traffic" + vpc_id = aws_vpc.main.id + ingress = [ + { + description = "Allow Bastion for SSH" + from_port = 22 + to_port = 22 + protocol = "tcp" + security_groups = [ + module.ssh_security_groups.security_group_ids["sg_ssh"] + ] + }, + { + description = "Allow All Traffics from IRIS" + from_port = 0 + to_port = 0 + protocol = "-1" + security_groups = [ + module.app_security_groups.security_group_ids["sg_ecs_iris"] + ] + }, + { + description = "Allow RabbitMQ Connection" + from_port = 5671 + to_port = 5671 + protocol = "tcp" + security_groups = [ + module.app_security_groups.security_group_ids["sg_ecs_api"] + ] + }, + { + description = "Allow ECS API for Log Data" + from_port = 443 + to_port = 443 + protocol = "tcp" + security_groups = [ + module.app_security_groups.security_group_ids["sg_ecs_api"] + ] + }, + { + description = "Allow ECS API for Log Data" + from_port = 3101 + to_port = 3101 + protocol = "tcp" + security_groups = [ + module.app_security_groups.security_group_ids["sg_ecs_api"] + ] + }, + { + description = "Allow ECS API for metric, trace data" + from_port = 4318 + to_port = 4318 + protocol = "tcp" + security_groups = [ + module.app_security_groups.security_group_ids["sg_ecs_api"] + ] + }, + ] + } + } +} diff --git a/apps/infra/rc/network/network/variables.tf b/apps/infra/rc/network/network/variables.tf new file mode 100644 index 0000000000..37691189d6 --- /dev/null +++ b/apps/infra/rc/network/network/variables.tf @@ -0,0 +1,27 @@ +variable "postgres_port" { + description = "Port for Postgres DB" + type = number + default = 5432 + sensitive = true +} + +variable "redis_port" { + description = "Port for Redis" + type = number + default = 6379 + sensitive = true +} + +variable "rabbitmq_port" { + type = string + default = "5671" + sensitive = true +} + +variable "region" { + type = string + description = "The region for provider" + default = "ap-northeast-2" +} + +variable "env" { sensitive = true } diff --git a/apps/infra/rc/network/network/vpc.tf b/apps/infra/rc/network/network/vpc.tf new file mode 100644 index 0000000000..298101cb39 --- /dev/null +++ b/apps/infra/rc/network/network/vpc.tf @@ -0,0 +1,40 @@ +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = "Codedang-VPC" + } +} + +#resource "aws_network_interface" "codedang_nat_instance" { +# subnet_id = module.public_api_subnets.subnet_ids["public_nat"] +# security_groups = [module.nat_security_groups.security_group_ids["sg_nat_instance"]] +# +# tags = { +# Name = "Codedang-eni" +# } +#} + + +resource "aws_vpc_endpoint" "s3_endpoint" { + vpc_id = aws_vpc.main.id + service_name = "com.amazonaws.${var.region}.s3" + vpc_endpoint_type = "Gateway" + route_table_ids = [aws_route_table.private.id] + + policy = jsonencode({ + Version = "2008-10-17" + Statement = [ + { + Action = "*", + Effect = "Allow", + Resource = "*", + Principal = "*" + } + ] + }) + + tags = { + "Name" = "S3-Gateway-Endpoint-for-Private-RT" + } +} \ No newline at end of file diff --git a/apps/infra/rc/network/storage/README.md b/apps/infra/rc/network/storage/README.md new file mode 100644 index 0000000000..ae4d4ef4f9 --- /dev/null +++ b/apps/infra/rc/network/storage/README.md @@ -0,0 +1,63 @@ +# Storage + +Project for Storage + +DB, Redis, S3 버킷들을 관리하는 프로젝트입니다. + + +## Requirements + +| Name | Version | +|------|---------| +| [aws](#requirement\_aws) | ~>5.0 | +| [random](#requirement\_random) | ~>3.6 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.52.0 | +| [random](#provider\_random) | 3.6.2 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_db_instance.postgres](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance) | resource | +| [aws_db_subnet_group.db_subnet_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource | +| [aws_elasticache_cluster.db_cache](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_cluster) | resource | +| [aws_elasticache_subnet_group.redis_subnet_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_subnet_group) | resource | +| [aws_s3_bucket.media](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket.testcase](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_policy.media](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | +| [aws_s3_bucket_policy.testcase](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | +| [aws_s3_bucket_public_access_block.media_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource | +| [aws_security_group.db](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group.redis](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_subnet.private_db1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_subnet.private_db2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_subnet.private_db3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_subnet.private_redis1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_subnet.private_redis2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [random_password.postgres_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | +| [aws_eip.nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eip) | data source | +| [aws_iam_policy_document.media_get_object](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.testcase_permissions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_vpc.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [postgres\_port](#input\_postgres\_port) | Port for Postgres DB | `number` | `5432` | no | +| [postgres\_username](#input\_postgres\_username) | Username for Postgres DB | `string` | `"skkuding"` | no | +| [redis\_port](#input\_redis\_port) | Port for Redis | `number` | `6379` | no | + +## Outputs + +No outputs. + diff --git a/apps/infra/rc/network/storage/database.tf b/apps/infra/rc/network/storage/database.tf new file mode 100644 index 0000000000..0147e3354c --- /dev/null +++ b/apps/infra/rc/network/storage/database.tf @@ -0,0 +1,30 @@ +resource "aws_db_subnet_group" "db_subnet_group" { + name = "codedang-db-subnet-group" + subnet_ids = [ + local.network.subnet_ids["private_db1"], + local.network.subnet_ids["private_db2"], + local.network.subnet_ids["private_db3"] + ] +} + +resource "random_password" "postgres_password" { + length = 16 + special = false +} + +resource "aws_db_instance" "postgres" { + db_name = "codedang_db" + engine = "postgres" + engine_version = "14" + allocated_storage = 5 + instance_class = "db.t4g.small" + + username = var.postgres_username + password = random_password.postgres_password.result + port = var.postgres_port + + vpc_security_group_ids = [local.network.security_group_ids["sg_db"]] + db_subnet_group_name = aws_db_subnet_group.db_subnet_group.name + + skip_final_snapshot = true +} diff --git a/apps/infra/rc/network/storage/ecr.tf b/apps/infra/rc/network/storage/ecr.tf new file mode 100644 index 0000000000..a6c1983707 --- /dev/null +++ b/apps/infra/rc/network/storage/ecr.tf @@ -0,0 +1,28 @@ +data "aws_ecr_repository" "repositories" { + for_each = toset(var.repository_names) + name = each.value +} + +resource "aws_ecr_lifecycle_policy" "repository_policy" { + for_each = data.aws_ecr_repository.repositories + + repository = each.value.name + policy = < [aws](#requirement\_aws) | ~>5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~>5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_dynamodb_table.tfstate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table) | resource | +| [aws_s3_bucket.tfstate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_versioning.tfstate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [region](#input\_region) | The region for provider | `string` | `"ap-northeast-2"` | no | + +## Outputs + +No outputs. diff --git a/apps/infra/rc/network/terraform-configuration/backend.tf b/apps/infra/rc/network/terraform-configuration/backend.tf new file mode 100644 index 0000000000..c59e145502 --- /dev/null +++ b/apps/infra/rc/network/terraform-configuration/backend.tf @@ -0,0 +1,21 @@ +resource "aws_s3_bucket" "tfstate" { + bucket = var.env == "production" ? "codedang-tf-state" : "codedang-tf-state-rc" +} + +resource "aws_s3_bucket_versioning" "tfstate" { + bucket = aws_s3_bucket.tfstate.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_dynamodb_table" "tfstate" { + name = "terraform-state-lock" + billing_mode = "PAY_PER_REQUEST" + hash_key = "LockID" + + attribute { + name = "LockID" + type = "S" + } +} diff --git a/apps/infra/rc/network/terraform-configuration/key_pair.tf b/apps/infra/rc/network/terraform-configuration/key_pair.tf new file mode 100644 index 0000000000..afd02b2a3e --- /dev/null +++ b/apps/infra/rc/network/terraform-configuration/key_pair.tf @@ -0,0 +1,11 @@ +resource "aws_s3_bucket" "key_pair" { + bucket = var.env == "production" ? "codedang-key-pair" : "codedang-key-pair-rc" +} + +module "key_pairs" { + source = "./modules/key_pair" + + bucket_name = aws_s3_bucket.key_pair.bucket + key_names = ["bastion-host", "nat-instance", "codedang-ecs-api-instance", "codedang-ecs-iris-instance"] + env = var.env +} \ No newline at end of file diff --git a/apps/infra/rc/network/terraform-configuration/main.tf b/apps/infra/rc/network/terraform-configuration/main.tf new file mode 100644 index 0000000000..74d0fd497c --- /dev/null +++ b/apps/infra/rc/network/terraform-configuration/main.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } +} + +provider "aws" { + region = var.region +} diff --git a/apps/infra/rc/network/terraform-configuration/modules/key_pair/key_pair.tf b/apps/infra/rc/network/terraform-configuration/modules/key_pair/key_pair.tf new file mode 100644 index 0000000000..e15e588953 --- /dev/null +++ b/apps/infra/rc/network/terraform-configuration/modules/key_pair/key_pair.tf @@ -0,0 +1,18 @@ +resource "tls_private_key" "this" { + for_each = toset(var.key_names) + algorithm = "RSA" + rsa_bits = 2048 +} + +resource "aws_key_pair" "this" { + for_each = tls_private_key.this + key_name = each.key + public_key = each.value.public_key_openssh +} + +resource "aws_s3_object" "this" { + for_each = toset(var.key_names) + bucket = var.bucket_name + key = "${each.key}.pem" + content = tls_private_key.this[each.key].private_key_pem +} \ No newline at end of file diff --git a/apps/infra/rc/network/terraform-configuration/modules/key_pair/main.tf b/apps/infra/rc/network/terraform-configuration/modules/key_pair/main.tf new file mode 100644 index 0000000000..a4d58d6b0f --- /dev/null +++ b/apps/infra/rc/network/terraform-configuration/modules/key_pair/main.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } + +} + +provider "aws" { + region = "ap-northeast-2" +} \ No newline at end of file diff --git a/apps/infra/rc/network/terraform-configuration/modules/key_pair/variables.tf b/apps/infra/rc/network/terraform-configuration/modules/key_pair/variables.tf new file mode 100644 index 0000000000..48c9ad8de4 --- /dev/null +++ b/apps/infra/rc/network/terraform-configuration/modules/key_pair/variables.tf @@ -0,0 +1,11 @@ +variable "key_names" { + type = list(string) + description = "The name of keys e.g. ['bastion-host', 'codedang-ecs-api-instance']" +} + +variable "bucket_name" { + type = string + description = "The name of key_pair bucket e.g. 'codedang-key-pair-rc" +} + +variable "env" { sensitive = true } diff --git a/apps/infra/rc/network/terraform-configuration/variables.tf b/apps/infra/rc/network/terraform-configuration/variables.tf new file mode 100644 index 0000000000..75e75ddf3e --- /dev/null +++ b/apps/infra/rc/network/terraform-configuration/variables.tf @@ -0,0 +1,7 @@ +variable "region" { + type = string + description = "The region for provider" + default = "ap-northeast-2" +} + +variable "env" { sensitive = true } \ No newline at end of file From 49b15131e717d2f9673d9beabb0358eb7dfe6da7 Mon Sep 17 00:00:00 2001 From: bocklag Date: Sun, 15 Dec 2024 16:44:43 +0000 Subject: [PATCH 2/3] feat(infra): refactor rc-server Terraform files --- apps/infra/rc/{network => }/codedang/README.md | 0 .../rc/{network => }/codedang/cloudfront.tf | 14 +++++++------- .../rc/{network => }/codedang/codedang_api.tf | 0 .../rc/{network => }/codedang/codedang_iris.tf | 0 .../codedang/codedang_service_admin.tf | 2 +- .../codedang/codedang_service_client.tf | 2 +- .../codedang/codedang_service_iris.tf | 0 .../container_definitions/admin_api.json | 0 .../container_definitions/client_api.json | 0 .../codedang/container_definitions/iris.json | 0 .../container_definitions/log_router.json | 0 .../codedang/iam_ecs_instance_role.tf | 0 .../codedang/iam_ecs_task_execution_role.tf | 0 apps/infra/rc/{network => }/codedang/main.tf | 0 .../rc/{network => }/codedang/message_queue.tf | 0 .../modules/cluster_autoscaling/README.md | 0 .../modules/cluster_autoscaling/autoscaling.tf | 2 +- .../modules/cluster_autoscaling/cluster.tf | 0 .../launch_template/user_data.sh | 0 .../modules/cluster_autoscaling/main.tf | 0 .../modules/cluster_autoscaling/outputs.tf | 0 .../modules/cluster_autoscaling/variables.tf | 4 ++-- .../codedang/modules/loadbalancing/README.md | 0 .../modules/loadbalancing/loadbalancing.tf | 2 +- .../codedang/modules/loadbalancing/main.tf | 0 .../codedang/modules/loadbalancing/outputs.tf | 0 .../modules/loadbalancing/variables.tf | 2 +- .../modules/service_autoscaling/README.md | 0 .../appautoscaling_scale_down.tf | 0 .../appautoscaling_scale_up.tf | 0 .../modules/service_autoscaling/ecs_service.tf | 0 .../service_autoscaling/iam_task_role.tf | 0 .../modules/service_autoscaling/main.tf | 0 .../modules/service_autoscaling/outputs.tf | 0 .../modules/service_autoscaling/variables.tf | 0 .../rc/{network => }/codedang/variables.tf | 0 apps/infra/rc/network/{network => }/README.md | 0 .../rc/network/{network => }/elastic_ip.tf | 0 apps/infra/rc/network/{network => }/main.tf | 0 .../modules/security_group/main.tf | 0 .../modules/security_group/outputs.tf | 0 .../modules/security_group/security_group.tf | 0 .../modules/security_group/variables.tf | 0 .../{network => }/modules/subnet/main.tf | 0 .../{network => }/modules/subnet/outputs.tf | 0 .../{network => }/modules/subnet/subnet.tf | 0 .../{network => }/modules/subnet/variables.tf | 0 .../network/{network => }/network_instance.tf | 0 apps/infra/rc/network/{network => }/outputs.tf | 8 ++++---- .../network/{network => }/private_network.tf | 0 .../rc/network/{network => }/public_network.tf | 0 apps/infra/rc/network/{network => }/route53.tf | 0 .../rc/network/{network => }/security_group.tf | 0 .../modules/key_pair/key_pair.tf | 18 ------------------ .../rc/network/{network => }/variables.tf | 0 apps/infra/rc/network/{network => }/vpc.tf | 0 apps/infra/rc/{network => }/storage/README.md | 0 .../infra/rc/{network => }/storage/database.tf | 0 apps/infra/rc/{network => }/storage/ecr.tf | 2 +- apps/infra/rc/{network => }/storage/main.tf | 0 .../{network => }/storage/message_queue_aws.tf | 0 apps/infra/rc/{network => }/storage/outputs.tf | 18 +++++++++--------- apps/infra/rc/{network => }/storage/redis.tf | 0 .../infra/rc/{network => }/storage/s3_media.tf | 0 .../{network => }/storage/s3_media_iam_user.tf | 0 .../rc/{network => }/storage/s3_testcase.tf | 0 .../storage/s3_testcase_iam_user.tf | 0 .../rc/{network => }/storage/variables.tf | 0 .../terraform-configuration/README.md | 0 .../terraform-configuration/backend.tf | 0 .../terraform-configuration/key_pair.tf | 4 ++-- .../terraform-configuration/main.tf | 0 .../modules/key_pair/key_pair.tf | 18 ++++++++++++++++++ .../modules/key_pair/main.tf | 0 .../modules/key_pair/variables.tf | 0 .../terraform-configuration/variables.tf | 0 76 files changed, 48 insertions(+), 48 deletions(-) rename apps/infra/rc/{network => }/codedang/README.md (100%) rename apps/infra/rc/{network => }/codedang/cloudfront.tf (89%) rename apps/infra/rc/{network => }/codedang/codedang_api.tf (100%) rename apps/infra/rc/{network => }/codedang/codedang_iris.tf (100%) rename apps/infra/rc/{network => }/codedang/codedang_service_admin.tf (98%) rename apps/infra/rc/{network => }/codedang/codedang_service_client.tf (98%) rename apps/infra/rc/{network => }/codedang/codedang_service_iris.tf (100%) rename apps/infra/rc/{network => }/codedang/container_definitions/admin_api.json (100%) rename apps/infra/rc/{network => }/codedang/container_definitions/client_api.json (100%) rename apps/infra/rc/{network => }/codedang/container_definitions/iris.json (100%) rename apps/infra/rc/{network => }/codedang/container_definitions/log_router.json (100%) rename apps/infra/rc/{network => }/codedang/iam_ecs_instance_role.tf (100%) rename apps/infra/rc/{network => }/codedang/iam_ecs_task_execution_role.tf (100%) rename apps/infra/rc/{network => }/codedang/main.tf (100%) rename apps/infra/rc/{network => }/codedang/message_queue.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/cluster_autoscaling/README.md (100%) rename apps/infra/rc/{network => }/codedang/modules/cluster_autoscaling/autoscaling.tf (97%) rename apps/infra/rc/{network => }/codedang/modules/cluster_autoscaling/cluster.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/cluster_autoscaling/launch_template/user_data.sh (100%) rename apps/infra/rc/{network => }/codedang/modules/cluster_autoscaling/main.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/cluster_autoscaling/outputs.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/cluster_autoscaling/variables.tf (95%) rename apps/infra/rc/{network => }/codedang/modules/loadbalancing/README.md (100%) rename apps/infra/rc/{network => }/codedang/modules/loadbalancing/loadbalancing.tf (96%) rename apps/infra/rc/{network => }/codedang/modules/loadbalancing/main.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/loadbalancing/outputs.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/loadbalancing/variables.tf (94%) rename apps/infra/rc/{network => }/codedang/modules/service_autoscaling/README.md (100%) rename apps/infra/rc/{network => }/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/service_autoscaling/ecs_service.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/service_autoscaling/iam_task_role.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/service_autoscaling/main.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/service_autoscaling/outputs.tf (100%) rename apps/infra/rc/{network => }/codedang/modules/service_autoscaling/variables.tf (100%) rename apps/infra/rc/{network => }/codedang/variables.tf (100%) rename apps/infra/rc/network/{network => }/README.md (100%) rename apps/infra/rc/network/{network => }/elastic_ip.tf (100%) rename apps/infra/rc/network/{network => }/main.tf (100%) rename apps/infra/rc/network/{network => }/modules/security_group/main.tf (100%) rename apps/infra/rc/network/{network => }/modules/security_group/outputs.tf (100%) rename apps/infra/rc/network/{network => }/modules/security_group/security_group.tf (100%) rename apps/infra/rc/network/{network => }/modules/security_group/variables.tf (100%) rename apps/infra/rc/network/{network => }/modules/subnet/main.tf (100%) rename apps/infra/rc/network/{network => }/modules/subnet/outputs.tf (100%) rename apps/infra/rc/network/{network => }/modules/subnet/subnet.tf (100%) rename apps/infra/rc/network/{network => }/modules/subnet/variables.tf (100%) rename apps/infra/rc/network/{network => }/network_instance.tf (100%) rename apps/infra/rc/network/{network => }/outputs.tf (87%) rename apps/infra/rc/network/{network => }/private_network.tf (100%) rename apps/infra/rc/network/{network => }/public_network.tf (100%) rename apps/infra/rc/network/{network => }/route53.tf (100%) rename apps/infra/rc/network/{network => }/security_group.tf (100%) delete mode 100644 apps/infra/rc/network/terraform-configuration/modules/key_pair/key_pair.tf rename apps/infra/rc/network/{network => }/variables.tf (100%) rename apps/infra/rc/network/{network => }/vpc.tf (100%) rename apps/infra/rc/{network => }/storage/README.md (100%) rename apps/infra/rc/{network => }/storage/database.tf (100%) rename apps/infra/rc/{network => }/storage/ecr.tf (96%) rename apps/infra/rc/{network => }/storage/main.tf (100%) rename apps/infra/rc/{network => }/storage/message_queue_aws.tf (100%) rename apps/infra/rc/{network => }/storage/outputs.tf (68%) rename apps/infra/rc/{network => }/storage/redis.tf (100%) rename apps/infra/rc/{network => }/storage/s3_media.tf (100%) rename apps/infra/rc/{network => }/storage/s3_media_iam_user.tf (100%) rename apps/infra/rc/{network => }/storage/s3_testcase.tf (100%) rename apps/infra/rc/{network => }/storage/s3_testcase_iam_user.tf (100%) rename apps/infra/rc/{network => }/storage/variables.tf (100%) rename apps/infra/rc/{network => }/terraform-configuration/README.md (100%) rename apps/infra/rc/{network => }/terraform-configuration/backend.tf (100%) rename apps/infra/rc/{network => }/terraform-configuration/key_pair.tf (62%) rename apps/infra/rc/{network => }/terraform-configuration/main.tf (100%) create mode 100644 apps/infra/rc/terraform-configuration/modules/key_pair/key_pair.tf rename apps/infra/rc/{network => }/terraform-configuration/modules/key_pair/main.tf (100%) rename apps/infra/rc/{network => }/terraform-configuration/modules/key_pair/variables.tf (100%) rename apps/infra/rc/{network => }/terraform-configuration/variables.tf (100%) diff --git a/apps/infra/rc/network/codedang/README.md b/apps/infra/rc/codedang/README.md similarity index 100% rename from apps/infra/rc/network/codedang/README.md rename to apps/infra/rc/codedang/README.md diff --git a/apps/infra/rc/network/codedang/cloudfront.tf b/apps/infra/rc/codedang/cloudfront.tf similarity index 89% rename from apps/infra/rc/network/codedang/cloudfront.tf rename to apps/infra/rc/codedang/cloudfront.tf index 3c8d5b00a4..ca256f1bd1 100644 --- a/apps/infra/rc/network/codedang/cloudfront.tf +++ b/apps/infra/rc/codedang/cloudfront.tf @@ -67,9 +67,9 @@ resource "aws_cloudfront_distribution" "codedang" { } ordered_cache_behavior { - path_pattern = "/api/*" - allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"] - cached_methods = ["GET", "HEAD", "OPTIONS"] + path_pattern = "/api/*" + allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"] + cached_methods = ["GET", "HEAD", "OPTIONS"] target_origin_id = module.client_api_loadbalancer.aws_lb_id viewer_protocol_policy = "redirect-to-https" cache_policy_id = data.aws_cloudfront_cache_policy.disable.id @@ -77,9 +77,9 @@ resource "aws_cloudfront_distribution" "codedang" { } ordered_cache_behavior { - path_pattern = "/graphql" - allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"] - cached_methods = ["GET", "HEAD", "OPTIONS"] + path_pattern = "/graphql" + allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"] + cached_methods = ["GET", "HEAD", "OPTIONS"] target_origin_id = module.admin_api_loadbalancer.aws_lb_id viewer_protocol_policy = "redirect-to-https" cache_policy_id = data.aws_cloudfront_cache_policy.disable.id @@ -101,7 +101,7 @@ resource "aws_cloudfront_distribution" "codedang" { } resource "aws_route53_record" "codedang" { - count = var.env == "production" ? 1 : 0 + count = var.env == "production" ? 1 : 0 name = "codedang.com" type = "A" zone_id = var.env == "rc" ? "" : local.network.route53_zone_id diff --git a/apps/infra/rc/network/codedang/codedang_api.tf b/apps/infra/rc/codedang/codedang_api.tf similarity index 100% rename from apps/infra/rc/network/codedang/codedang_api.tf rename to apps/infra/rc/codedang/codedang_api.tf diff --git a/apps/infra/rc/network/codedang/codedang_iris.tf b/apps/infra/rc/codedang/codedang_iris.tf similarity index 100% rename from apps/infra/rc/network/codedang/codedang_iris.tf rename to apps/infra/rc/codedang/codedang_iris.tf diff --git a/apps/infra/rc/network/codedang/codedang_service_admin.tf b/apps/infra/rc/codedang/codedang_service_admin.tf similarity index 98% rename from apps/infra/rc/network/codedang/codedang_service_admin.tf rename to apps/infra/rc/codedang/codedang_service_admin.tf index 4481efa77c..2b2439080d 100644 --- a/apps/infra/rc/network/codedang/codedang_service_admin.tf +++ b/apps/infra/rc/codedang/codedang_service_admin.tf @@ -6,7 +6,7 @@ module "admin_api_loadbalancer" { source = "./modules/loadbalancing" lb = { - name = "Codedang-Admin-Api-LB" + name = "Codedang-Admin-Api-LB" subnets = ["public1", "public2"] } diff --git a/apps/infra/rc/network/codedang/codedang_service_client.tf b/apps/infra/rc/codedang/codedang_service_client.tf similarity index 98% rename from apps/infra/rc/network/codedang/codedang_service_client.tf rename to apps/infra/rc/codedang/codedang_service_client.tf index 617da60565..422e4a71f0 100644 --- a/apps/infra/rc/network/codedang/codedang_service_client.tf +++ b/apps/infra/rc/codedang/codedang_service_client.tf @@ -6,7 +6,7 @@ module "client_api_loadbalancer" { source = "./modules/loadbalancing" lb = { - name = "Codedang-Client-Api-LB" + name = "Codedang-Client-Api-LB" subnets = ["public1", "public2"] } diff --git a/apps/infra/rc/network/codedang/codedang_service_iris.tf b/apps/infra/rc/codedang/codedang_service_iris.tf similarity index 100% rename from apps/infra/rc/network/codedang/codedang_service_iris.tf rename to apps/infra/rc/codedang/codedang_service_iris.tf diff --git a/apps/infra/rc/network/codedang/container_definitions/admin_api.json b/apps/infra/rc/codedang/container_definitions/admin_api.json similarity index 100% rename from apps/infra/rc/network/codedang/container_definitions/admin_api.json rename to apps/infra/rc/codedang/container_definitions/admin_api.json diff --git a/apps/infra/rc/network/codedang/container_definitions/client_api.json b/apps/infra/rc/codedang/container_definitions/client_api.json similarity index 100% rename from apps/infra/rc/network/codedang/container_definitions/client_api.json rename to apps/infra/rc/codedang/container_definitions/client_api.json diff --git a/apps/infra/rc/network/codedang/container_definitions/iris.json b/apps/infra/rc/codedang/container_definitions/iris.json similarity index 100% rename from apps/infra/rc/network/codedang/container_definitions/iris.json rename to apps/infra/rc/codedang/container_definitions/iris.json diff --git a/apps/infra/rc/network/codedang/container_definitions/log_router.json b/apps/infra/rc/codedang/container_definitions/log_router.json similarity index 100% rename from apps/infra/rc/network/codedang/container_definitions/log_router.json rename to apps/infra/rc/codedang/container_definitions/log_router.json diff --git a/apps/infra/rc/network/codedang/iam_ecs_instance_role.tf b/apps/infra/rc/codedang/iam_ecs_instance_role.tf similarity index 100% rename from apps/infra/rc/network/codedang/iam_ecs_instance_role.tf rename to apps/infra/rc/codedang/iam_ecs_instance_role.tf diff --git a/apps/infra/rc/network/codedang/iam_ecs_task_execution_role.tf b/apps/infra/rc/codedang/iam_ecs_task_execution_role.tf similarity index 100% rename from apps/infra/rc/network/codedang/iam_ecs_task_execution_role.tf rename to apps/infra/rc/codedang/iam_ecs_task_execution_role.tf diff --git a/apps/infra/rc/network/codedang/main.tf b/apps/infra/rc/codedang/main.tf similarity index 100% rename from apps/infra/rc/network/codedang/main.tf rename to apps/infra/rc/codedang/main.tf diff --git a/apps/infra/rc/network/codedang/message_queue.tf b/apps/infra/rc/codedang/message_queue.tf similarity index 100% rename from apps/infra/rc/network/codedang/message_queue.tf rename to apps/infra/rc/codedang/message_queue.tf diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/README.md b/apps/infra/rc/codedang/modules/cluster_autoscaling/README.md similarity index 100% rename from apps/infra/rc/network/codedang/modules/cluster_autoscaling/README.md rename to apps/infra/rc/codedang/modules/cluster_autoscaling/README.md diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/autoscaling.tf b/apps/infra/rc/codedang/modules/cluster_autoscaling/autoscaling.tf similarity index 97% rename from apps/infra/rc/network/codedang/modules/cluster_autoscaling/autoscaling.tf rename to apps/infra/rc/codedang/modules/cluster_autoscaling/autoscaling.tf index 820630f01a..51f2753b28 100644 --- a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/autoscaling.tf +++ b/apps/infra/rc/codedang/modules/cluster_autoscaling/autoscaling.tf @@ -24,7 +24,7 @@ resource "aws_launch_template" "this" { } resource "aws_autoscaling_group" "this" { - name = var.autoscaling_group.name + name = var.autoscaling_group.name vpc_zone_identifier = [for name in var.subnets : local.network.subnet_ids[name]] desired_capacity = var.autoscaling_group.desired_capacity diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/cluster.tf b/apps/infra/rc/codedang/modules/cluster_autoscaling/cluster.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/cluster_autoscaling/cluster.tf rename to apps/infra/rc/codedang/modules/cluster_autoscaling/cluster.tf diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/launch_template/user_data.sh b/apps/infra/rc/codedang/modules/cluster_autoscaling/launch_template/user_data.sh similarity index 100% rename from apps/infra/rc/network/codedang/modules/cluster_autoscaling/launch_template/user_data.sh rename to apps/infra/rc/codedang/modules/cluster_autoscaling/launch_template/user_data.sh diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/main.tf b/apps/infra/rc/codedang/modules/cluster_autoscaling/main.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/cluster_autoscaling/main.tf rename to apps/infra/rc/codedang/modules/cluster_autoscaling/main.tf diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/outputs.tf b/apps/infra/rc/codedang/modules/cluster_autoscaling/outputs.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/cluster_autoscaling/outputs.tf rename to apps/infra/rc/codedang/modules/cluster_autoscaling/outputs.tf diff --git a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/variables.tf b/apps/infra/rc/codedang/modules/cluster_autoscaling/variables.tf similarity index 95% rename from apps/infra/rc/network/codedang/modules/cluster_autoscaling/variables.tf rename to apps/infra/rc/codedang/modules/cluster_autoscaling/variables.tf index 4c69a9691a..24aeab95a1 100644 --- a/apps/infra/rc/network/codedang/modules/cluster_autoscaling/variables.tf +++ b/apps/infra/rc/codedang/modules/cluster_autoscaling/variables.tf @@ -37,11 +37,11 @@ variable "ecs_capacity_provider_name" { } variable "subnets" { - type = list(string) + type = list(string) description = "List of subnet names. e.g. ['private_api1', 'private_api2']" } variable "security_groups" { - type = list(string) + type = list(string) description = "List of SG names. e.g. ['sg_db', 'sg_redis']" } \ No newline at end of file diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/README.md b/apps/infra/rc/codedang/modules/loadbalancing/README.md similarity index 100% rename from apps/infra/rc/network/codedang/modules/loadbalancing/README.md rename to apps/infra/rc/codedang/modules/loadbalancing/README.md diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/loadbalancing.tf b/apps/infra/rc/codedang/modules/loadbalancing/loadbalancing.tf similarity index 96% rename from apps/infra/rc/network/codedang/modules/loadbalancing/loadbalancing.tf rename to apps/infra/rc/codedang/modules/loadbalancing/loadbalancing.tf index f33e441b42..92a84d9b8f 100644 --- a/apps/infra/rc/network/codedang/modules/loadbalancing/loadbalancing.tf +++ b/apps/infra/rc/codedang/modules/loadbalancing/loadbalancing.tf @@ -12,7 +12,7 @@ resource "aws_lb_target_group" "this" { target_type = "instance" port = var.lb_target_group.port protocol = "HTTP" - vpc_id = local.network.vpc_id + vpc_id = local.network.vpc_id health_check { interval = 30 diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/main.tf b/apps/infra/rc/codedang/modules/loadbalancing/main.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/loadbalancing/main.tf rename to apps/infra/rc/codedang/modules/loadbalancing/main.tf diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/outputs.tf b/apps/infra/rc/codedang/modules/loadbalancing/outputs.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/loadbalancing/outputs.tf rename to apps/infra/rc/codedang/modules/loadbalancing/outputs.tf diff --git a/apps/infra/rc/network/codedang/modules/loadbalancing/variables.tf b/apps/infra/rc/codedang/modules/loadbalancing/variables.tf similarity index 94% rename from apps/infra/rc/network/codedang/modules/loadbalancing/variables.tf rename to apps/infra/rc/codedang/modules/loadbalancing/variables.tf index f4d91f097b..98a31a07ea 100644 --- a/apps/infra/rc/network/codedang/modules/loadbalancing/variables.tf +++ b/apps/infra/rc/codedang/modules/loadbalancing/variables.tf @@ -16,6 +16,6 @@ variable "lb_target_group" { } variable "security_groups" { - type = list(string) + type = list(string) description = "List of SG names. e.g. ['sg_db', 'sg_redis']" } diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/README.md b/apps/infra/rc/codedang/modules/service_autoscaling/README.md similarity index 100% rename from apps/infra/rc/network/codedang/modules/service_autoscaling/README.md rename to apps/infra/rc/codedang/modules/service_autoscaling/README.md diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf b/apps/infra/rc/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf rename to apps/infra/rc/codedang/modules/service_autoscaling/appautoscaling_scale_down.tf diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf b/apps/infra/rc/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf rename to apps/infra/rc/codedang/modules/service_autoscaling/appautoscaling_scale_up.tf diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/ecs_service.tf b/apps/infra/rc/codedang/modules/service_autoscaling/ecs_service.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/service_autoscaling/ecs_service.tf rename to apps/infra/rc/codedang/modules/service_autoscaling/ecs_service.tf diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/iam_task_role.tf b/apps/infra/rc/codedang/modules/service_autoscaling/iam_task_role.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/service_autoscaling/iam_task_role.tf rename to apps/infra/rc/codedang/modules/service_autoscaling/iam_task_role.tf diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/main.tf b/apps/infra/rc/codedang/modules/service_autoscaling/main.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/service_autoscaling/main.tf rename to apps/infra/rc/codedang/modules/service_autoscaling/main.tf diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/outputs.tf b/apps/infra/rc/codedang/modules/service_autoscaling/outputs.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/service_autoscaling/outputs.tf rename to apps/infra/rc/codedang/modules/service_autoscaling/outputs.tf diff --git a/apps/infra/rc/network/codedang/modules/service_autoscaling/variables.tf b/apps/infra/rc/codedang/modules/service_autoscaling/variables.tf similarity index 100% rename from apps/infra/rc/network/codedang/modules/service_autoscaling/variables.tf rename to apps/infra/rc/codedang/modules/service_autoscaling/variables.tf diff --git a/apps/infra/rc/network/codedang/variables.tf b/apps/infra/rc/codedang/variables.tf similarity index 100% rename from apps/infra/rc/network/codedang/variables.tf rename to apps/infra/rc/codedang/variables.tf diff --git a/apps/infra/rc/network/network/README.md b/apps/infra/rc/network/README.md similarity index 100% rename from apps/infra/rc/network/network/README.md rename to apps/infra/rc/network/README.md diff --git a/apps/infra/rc/network/network/elastic_ip.tf b/apps/infra/rc/network/elastic_ip.tf similarity index 100% rename from apps/infra/rc/network/network/elastic_ip.tf rename to apps/infra/rc/network/elastic_ip.tf diff --git a/apps/infra/rc/network/network/main.tf b/apps/infra/rc/network/main.tf similarity index 100% rename from apps/infra/rc/network/network/main.tf rename to apps/infra/rc/network/main.tf diff --git a/apps/infra/rc/network/network/modules/security_group/main.tf b/apps/infra/rc/network/modules/security_group/main.tf similarity index 100% rename from apps/infra/rc/network/network/modules/security_group/main.tf rename to apps/infra/rc/network/modules/security_group/main.tf diff --git a/apps/infra/rc/network/network/modules/security_group/outputs.tf b/apps/infra/rc/network/modules/security_group/outputs.tf similarity index 100% rename from apps/infra/rc/network/network/modules/security_group/outputs.tf rename to apps/infra/rc/network/modules/security_group/outputs.tf diff --git a/apps/infra/rc/network/network/modules/security_group/security_group.tf b/apps/infra/rc/network/modules/security_group/security_group.tf similarity index 100% rename from apps/infra/rc/network/network/modules/security_group/security_group.tf rename to apps/infra/rc/network/modules/security_group/security_group.tf diff --git a/apps/infra/rc/network/network/modules/security_group/variables.tf b/apps/infra/rc/network/modules/security_group/variables.tf similarity index 100% rename from apps/infra/rc/network/network/modules/security_group/variables.tf rename to apps/infra/rc/network/modules/security_group/variables.tf diff --git a/apps/infra/rc/network/network/modules/subnet/main.tf b/apps/infra/rc/network/modules/subnet/main.tf similarity index 100% rename from apps/infra/rc/network/network/modules/subnet/main.tf rename to apps/infra/rc/network/modules/subnet/main.tf diff --git a/apps/infra/rc/network/network/modules/subnet/outputs.tf b/apps/infra/rc/network/modules/subnet/outputs.tf similarity index 100% rename from apps/infra/rc/network/network/modules/subnet/outputs.tf rename to apps/infra/rc/network/modules/subnet/outputs.tf diff --git a/apps/infra/rc/network/network/modules/subnet/subnet.tf b/apps/infra/rc/network/modules/subnet/subnet.tf similarity index 100% rename from apps/infra/rc/network/network/modules/subnet/subnet.tf rename to apps/infra/rc/network/modules/subnet/subnet.tf diff --git a/apps/infra/rc/network/network/modules/subnet/variables.tf b/apps/infra/rc/network/modules/subnet/variables.tf similarity index 100% rename from apps/infra/rc/network/network/modules/subnet/variables.tf rename to apps/infra/rc/network/modules/subnet/variables.tf diff --git a/apps/infra/rc/network/network/network_instance.tf b/apps/infra/rc/network/network_instance.tf similarity index 100% rename from apps/infra/rc/network/network/network_instance.tf rename to apps/infra/rc/network/network_instance.tf diff --git a/apps/infra/rc/network/network/outputs.tf b/apps/infra/rc/network/outputs.tf similarity index 87% rename from apps/infra/rc/network/network/outputs.tf rename to apps/infra/rc/network/outputs.tf index 0bc55424d6..3ab48e21f8 100644 --- a/apps/infra/rc/network/network/outputs.tf +++ b/apps/infra/rc/network/outputs.tf @@ -1,20 +1,20 @@ output "vpc_id" { - value = aws_vpc.main.id + value = aws_vpc.main.id sensitive = true } output "private_route_table_id" { - value = aws_route_table.private.id + value = aws_route_table.private.id sensitive = true } output "public_ip" { - value = aws_eip.nat_instance.public_ip + value = aws_eip.nat_instance.public_ip sensitive = true } output "mq_subnet_id" { - value = aws_subnet.private_mq.id + value = aws_subnet.private_mq.id sensitive = true } diff --git a/apps/infra/rc/network/network/private_network.tf b/apps/infra/rc/network/private_network.tf similarity index 100% rename from apps/infra/rc/network/network/private_network.tf rename to apps/infra/rc/network/private_network.tf diff --git a/apps/infra/rc/network/network/public_network.tf b/apps/infra/rc/network/public_network.tf similarity index 100% rename from apps/infra/rc/network/network/public_network.tf rename to apps/infra/rc/network/public_network.tf diff --git a/apps/infra/rc/network/network/route53.tf b/apps/infra/rc/network/route53.tf similarity index 100% rename from apps/infra/rc/network/network/route53.tf rename to apps/infra/rc/network/route53.tf diff --git a/apps/infra/rc/network/network/security_group.tf b/apps/infra/rc/network/security_group.tf similarity index 100% rename from apps/infra/rc/network/network/security_group.tf rename to apps/infra/rc/network/security_group.tf diff --git a/apps/infra/rc/network/terraform-configuration/modules/key_pair/key_pair.tf b/apps/infra/rc/network/terraform-configuration/modules/key_pair/key_pair.tf deleted file mode 100644 index e15e588953..0000000000 --- a/apps/infra/rc/network/terraform-configuration/modules/key_pair/key_pair.tf +++ /dev/null @@ -1,18 +0,0 @@ -resource "tls_private_key" "this" { - for_each = toset(var.key_names) - algorithm = "RSA" - rsa_bits = 2048 -} - -resource "aws_key_pair" "this" { - for_each = tls_private_key.this - key_name = each.key - public_key = each.value.public_key_openssh -} - -resource "aws_s3_object" "this" { - for_each = toset(var.key_names) - bucket = var.bucket_name - key = "${each.key}.pem" - content = tls_private_key.this[each.key].private_key_pem -} \ No newline at end of file diff --git a/apps/infra/rc/network/network/variables.tf b/apps/infra/rc/network/variables.tf similarity index 100% rename from apps/infra/rc/network/network/variables.tf rename to apps/infra/rc/network/variables.tf diff --git a/apps/infra/rc/network/network/vpc.tf b/apps/infra/rc/network/vpc.tf similarity index 100% rename from apps/infra/rc/network/network/vpc.tf rename to apps/infra/rc/network/vpc.tf diff --git a/apps/infra/rc/network/storage/README.md b/apps/infra/rc/storage/README.md similarity index 100% rename from apps/infra/rc/network/storage/README.md rename to apps/infra/rc/storage/README.md diff --git a/apps/infra/rc/network/storage/database.tf b/apps/infra/rc/storage/database.tf similarity index 100% rename from apps/infra/rc/network/storage/database.tf rename to apps/infra/rc/storage/database.tf diff --git a/apps/infra/rc/network/storage/ecr.tf b/apps/infra/rc/storage/ecr.tf similarity index 96% rename from apps/infra/rc/network/storage/ecr.tf rename to apps/infra/rc/storage/ecr.tf index a6c1983707..e89f47b631 100644 --- a/apps/infra/rc/network/storage/ecr.tf +++ b/apps/infra/rc/storage/ecr.tf @@ -1,6 +1,6 @@ data "aws_ecr_repository" "repositories" { for_each = toset(var.repository_names) - name = each.value + name = each.value } resource "aws_ecr_lifecycle_policy" "repository_policy" { diff --git a/apps/infra/rc/network/storage/main.tf b/apps/infra/rc/storage/main.tf similarity index 100% rename from apps/infra/rc/network/storage/main.tf rename to apps/infra/rc/storage/main.tf diff --git a/apps/infra/rc/network/storage/message_queue_aws.tf b/apps/infra/rc/storage/message_queue_aws.tf similarity index 100% rename from apps/infra/rc/network/storage/message_queue_aws.tf rename to apps/infra/rc/storage/message_queue_aws.tf diff --git a/apps/infra/rc/network/storage/outputs.tf b/apps/infra/rc/storage/outputs.tf similarity index 68% rename from apps/infra/rc/network/storage/outputs.tf rename to apps/infra/rc/storage/outputs.tf index a9778856b6..f4674bd2ac 100644 --- a/apps/infra/rc/network/storage/outputs.tf +++ b/apps/infra/rc/storage/outputs.tf @@ -4,37 +4,37 @@ output "db_url" { } output "redis_host" { - value = aws_elasticache_cluster.db_cache.cache_nodes[0].address + value = aws_elasticache_cluster.db_cache.cache_nodes[0].address sensitive = true } output "mq_host_id" { - value = aws_mq_broker.judge_queue.id + value = aws_mq_broker.judge_queue.id sensitive = true } output "mq_api_url" { - value = aws_mq_broker.judge_queue.instances.0.console_url + value = aws_mq_broker.judge_queue.instances.0.console_url sensitive = true } output "mq_password" { - value = random_password.rabbitmq_password.result + value = random_password.rabbitmq_password.result sensitive = true } output "s3_media_bucket" { value = { name = aws_s3_bucket.media.bucket - arn = aws_s3_bucket.media.arn + arn = aws_s3_bucket.media.arn } sensitive = true } output "s3_testcase_bucket" { - value = { + value = { name = aws_s3_bucket.testcase.bucket - arn = aws_s3_bucket.testcase.arn + arn = aws_s3_bucket.testcase.arn } sensitive = true } @@ -44,7 +44,7 @@ output "media_access_key" { } output "media_secret_access_key" { - value = aws_iam_access_key.media.secret + value = aws_iam_access_key.media.secret sensitive = true } @@ -53,6 +53,6 @@ output "testcase_access_key" { } output "testcase_secret_access_key" { - value = aws_iam_access_key.testcase.secret + value = aws_iam_access_key.testcase.secret sensitive = true } \ No newline at end of file diff --git a/apps/infra/rc/network/storage/redis.tf b/apps/infra/rc/storage/redis.tf similarity index 100% rename from apps/infra/rc/network/storage/redis.tf rename to apps/infra/rc/storage/redis.tf diff --git a/apps/infra/rc/network/storage/s3_media.tf b/apps/infra/rc/storage/s3_media.tf similarity index 100% rename from apps/infra/rc/network/storage/s3_media.tf rename to apps/infra/rc/storage/s3_media.tf diff --git a/apps/infra/rc/network/storage/s3_media_iam_user.tf b/apps/infra/rc/storage/s3_media_iam_user.tf similarity index 100% rename from apps/infra/rc/network/storage/s3_media_iam_user.tf rename to apps/infra/rc/storage/s3_media_iam_user.tf diff --git a/apps/infra/rc/network/storage/s3_testcase.tf b/apps/infra/rc/storage/s3_testcase.tf similarity index 100% rename from apps/infra/rc/network/storage/s3_testcase.tf rename to apps/infra/rc/storage/s3_testcase.tf diff --git a/apps/infra/rc/network/storage/s3_testcase_iam_user.tf b/apps/infra/rc/storage/s3_testcase_iam_user.tf similarity index 100% rename from apps/infra/rc/network/storage/s3_testcase_iam_user.tf rename to apps/infra/rc/storage/s3_testcase_iam_user.tf diff --git a/apps/infra/rc/network/storage/variables.tf b/apps/infra/rc/storage/variables.tf similarity index 100% rename from apps/infra/rc/network/storage/variables.tf rename to apps/infra/rc/storage/variables.tf diff --git a/apps/infra/rc/network/terraform-configuration/README.md b/apps/infra/rc/terraform-configuration/README.md similarity index 100% rename from apps/infra/rc/network/terraform-configuration/README.md rename to apps/infra/rc/terraform-configuration/README.md diff --git a/apps/infra/rc/network/terraform-configuration/backend.tf b/apps/infra/rc/terraform-configuration/backend.tf similarity index 100% rename from apps/infra/rc/network/terraform-configuration/backend.tf rename to apps/infra/rc/terraform-configuration/backend.tf diff --git a/apps/infra/rc/network/terraform-configuration/key_pair.tf b/apps/infra/rc/terraform-configuration/key_pair.tf similarity index 62% rename from apps/infra/rc/network/terraform-configuration/key_pair.tf rename to apps/infra/rc/terraform-configuration/key_pair.tf index afd02b2a3e..026052595c 100644 --- a/apps/infra/rc/network/terraform-configuration/key_pair.tf +++ b/apps/infra/rc/terraform-configuration/key_pair.tf @@ -6,6 +6,6 @@ module "key_pairs" { source = "./modules/key_pair" bucket_name = aws_s3_bucket.key_pair.bucket - key_names = ["bastion-host", "nat-instance", "codedang-ecs-api-instance", "codedang-ecs-iris-instance"] - env = var.env + key_names = ["bastion-host", "nat-instance", "codedang-ecs-api-instance", "codedang-ecs-iris-instance"] + env = var.env } \ No newline at end of file diff --git a/apps/infra/rc/network/terraform-configuration/main.tf b/apps/infra/rc/terraform-configuration/main.tf similarity index 100% rename from apps/infra/rc/network/terraform-configuration/main.tf rename to apps/infra/rc/terraform-configuration/main.tf diff --git a/apps/infra/rc/terraform-configuration/modules/key_pair/key_pair.tf b/apps/infra/rc/terraform-configuration/modules/key_pair/key_pair.tf new file mode 100644 index 0000000000..b871527bc1 --- /dev/null +++ b/apps/infra/rc/terraform-configuration/modules/key_pair/key_pair.tf @@ -0,0 +1,18 @@ +resource "tls_private_key" "this" { + for_each = toset(var.key_names) + algorithm = "RSA" + rsa_bits = 2048 +} + +resource "aws_key_pair" "this" { + for_each = tls_private_key.this + key_name = each.key + public_key = each.value.public_key_openssh +} + +resource "aws_s3_object" "this" { + for_each = toset(var.key_names) + bucket = var.bucket_name + key = "${each.key}.pem" + content = tls_private_key.this[each.key].private_key_pem +} \ No newline at end of file diff --git a/apps/infra/rc/network/terraform-configuration/modules/key_pair/main.tf b/apps/infra/rc/terraform-configuration/modules/key_pair/main.tf similarity index 100% rename from apps/infra/rc/network/terraform-configuration/modules/key_pair/main.tf rename to apps/infra/rc/terraform-configuration/modules/key_pair/main.tf diff --git a/apps/infra/rc/network/terraform-configuration/modules/key_pair/variables.tf b/apps/infra/rc/terraform-configuration/modules/key_pair/variables.tf similarity index 100% rename from apps/infra/rc/network/terraform-configuration/modules/key_pair/variables.tf rename to apps/infra/rc/terraform-configuration/modules/key_pair/variables.tf diff --git a/apps/infra/rc/network/terraform-configuration/variables.tf b/apps/infra/rc/terraform-configuration/variables.tf similarity index 100% rename from apps/infra/rc/network/terraform-configuration/variables.tf rename to apps/infra/rc/terraform-configuration/variables.tf From beb62e1cc78159d20c6decffb31aa703052bdc8c Mon Sep 17 00:00:00 2001 From: bocklag Date: Sat, 28 Dec 2024 06:53:07 +0000 Subject: [PATCH 3/3] feat(infra): rafactor re-server Terraform and Github Actions Files --- .github/workflows/rc-build-image.yml | 90 ++++++++++++++++ .github/workflows/rc-deploy-target.yml | 66 ++++++++++++ .github/workflows/rc-deploy.yml | 133 ++++++++++++++++++++++++ .github/workflows/rc-destroy-target.yml | 60 +++++++++++ .github/workflows/rc-destroy.yml | 74 +++++++++++++ .github/workflows/rc-init-config.yml | 50 +++++++++ apps/infra/rc/codedang/cloudfront.tf | 1 + 7 files changed, 474 insertions(+) create mode 100644 .github/workflows/rc-build-image.yml create mode 100644 .github/workflows/rc-deploy-target.yml create mode 100644 .github/workflows/rc-deploy.yml create mode 100644 .github/workflows/rc-destroy-target.yml create mode 100644 .github/workflows/rc-destroy.yml create mode 100644 .github/workflows/rc-init-config.yml diff --git a/.github/workflows/rc-build-image.yml b/.github/workflows/rc-build-image.yml new file mode 100644 index 0000000000..464ad3ea1a --- /dev/null +++ b/.github/workflows/rc-build-image.yml @@ -0,0 +1,90 @@ +name: RC - CD - Build Images + +on: + workflow_dispatch: + +env: + AWS_REGION: ap-northeast-2 + ECS_CLUSTER: Codedang-Api + +permissions: # permissions to the job (for the OpenID Connection) + id-token: write + contents: read + +jobs: + build-client-api: + name: Build client-api image + runs-on: ubuntu-latest + steps: + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_ECR_PUSH_RC }} + aws-region: ${{ env.AWS_REGION }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build and push image + uses: docker/build-push-action@v6 + with: + file: ./apps/backend/Dockerfile + push: true + build-args: | + target=client + app_env=production + tags: ${{ steps.login-ecr.outputs.registry }}/codedang-client-api:latest + + build-admin-api: + name: Build admin-api image + runs-on: ubuntu-latest + steps: + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_ECR_PUSH_RC }} + aws-region: ${{ env.AWS_REGION }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build and push image + uses: docker/build-push-action@v6 + with: + file: ./apps/backend/Dockerfile + push: true + build-args: | + target=admin + app_env=production + tags: ${{ steps.login-ecr.outputs.registry }}/codedang-admin-api:latest + + build-iris: + name: Build iris Docker image + runs-on: ubuntu-latest + steps: + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_ECR_PUSH_RC }} + aws-region: ${{ env.AWS_REGION }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build and push image (iris) + uses: docker/build-push-action@v6 + with: + push: true + context: '{{defaultContext}}:apps/iris' + build-args: | + app_env=production + tags: ${{ steps.login-ecr.outputs.registry }}/codedang-iris:latest diff --git a/.github/workflows/rc-deploy-target.yml b/.github/workflows/rc-deploy-target.yml new file mode 100644 index 0000000000..e40530fcea --- /dev/null +++ b/.github/workflows/rc-deploy-target.yml @@ -0,0 +1,66 @@ +name: RC - Deploy - Target + +on: + workflow_dispatch: + inputs: + terraform_project: + description: 'Select Terraform Project to Deploy' + required: true + type: choice + options: + - 'network' + - 'storage' + - 'codedang' + +env: + AWS_REGION: ap-northeast-2 + ECS_CLUSTER: Codedang-Api + +permissions: # permissions to the job (for the OpenID Connection) + id-token: write + contents: read + +jobs: + rc-deploy-target-project: + name: RC - Deploy Terraform targeted Project + runs-on: ubuntu-latest + environment: production + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v4 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_DEPLOY_RC }} + aws-region: ${{ env.AWS_REGION }} + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.5.2 + + - name: Create Terraform variable file + working-directory: ./apps/infra/rc/${{ github.event.inputs.terraform_project }} + run: | + echo "$TFVARS_RC" >> terraform.tfvars + echo "$OAUTH_GITHUB" >> terraform.tfvars + echo "$OAUTH_KAKAO" >> terraform.tfvars + echo 'env = "rc"' >> terraform.tfvars + env: + TFVARS_RC: ${{ secrets.TFVARS_RC }} + OAUTH_GITHUB: ${{ secrets.OAUTH_GITHUB }} + OAUTH_KAKAO: ${{ secrets.OAUTH_KAKAO }} + + - name: Terraform Init + working-directory: ./apps/infra/rc/${{ github.event.inputs.terraform_project }} + run: terraform init -backend-config="bucket=codedang-tf-state-rc" + + - name: Terraform Plan + working-directory: ./apps/infra/rc/${{ github.event.inputs.terraform_project }} + run: terraform plan -input=false -out=plan.out + + - name: Terraform Apply + working-directory: ./apps/infra/rc/${{ github.event.inputs.terraform_project }} + run: terraform apply -input=false plan.out diff --git a/.github/workflows/rc-deploy.yml b/.github/workflows/rc-deploy.yml new file mode 100644 index 0000000000..5b217dbd02 --- /dev/null +++ b/.github/workflows/rc-deploy.yml @@ -0,0 +1,133 @@ +name: RC - Deploy + +on: + workflow_dispatch: + +env: + AWS_REGION: ap-northeast-2 + ECS_CLUSTER: Codedang-Api + +permissions: # permissions to the job (for the OpenID Connection) + id-token: write + contents: read + +jobs: + rc-deploy-network: + name: RC - Deploy Network + runs-on: ubuntu-latest + environment: production + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v4 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_DEPLOY_RC }} + aws-region: ${{ env.AWS_REGION }} + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.5.2 + + - name: Create Terraform variable file + working-directory: ./apps/infra/rc/network + run: | + echo 'env = "rc"' >> terraform.tfvars + + - name: Terraform Init + working-directory: ./apps/infra/rc/network + run: terraform init -backend-config="bucket=codedang-tf-state-rc" + + - name: Terraform Plan + working-directory: ./apps/infra/rc/network + run: terraform plan -input=false -out=plan.out + + - name: Terraform Apply + working-directory: ./apps/infra/rc/network + run: terraform apply -input=false plan.out + + rc-deploy-storage: + name: RC - Deploy Storage + runs-on: ubuntu-latest + needs: [rc-deploy-network] + environment: production + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v4 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_DEPLOY_RC }} + aws-region: ${{ env.AWS_REGION }} + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.5.2 + + - name: Create Terraform variable file + working-directory: ./apps/infra/rc/storage + run: | + echo 'env = "rc"' >> terraform.tfvars + + - name: Terraform Init + working-directory: ./apps/infra/rc/storage + run: terraform init -backend-config="bucket=codedang-tf-state-rc" + + - name: Terraform Plan + working-directory: ./apps/infra/rc/storage + run: terraform plan -input=false -out=plan.out + + - name: Terraform Apply + working-directory: ./apps/infra/rc/storage + run: terraform apply -input=false plan.out + + rc-deploy-codedang: + name: RC - Deploy Codedang + runs-on: ubuntu-latest + needs: [rc-deploy-network, rc-deploy-storage] + environment: production + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v4 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_DEPLOY_RC }} + aws-region: ${{ env.AWS_REGION }} + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.5.2 + + - name: Create Terraform variable file + working-directory: ./apps/infra/rc/codedang + run: | + echo "$TFVARS_RC" >> terraform.tfvars + echo "$OAUTH_GITHUB" >> terraform.tfvars + echo "$OAUTH_KAKAO" >> terraform.tfvars + echo 'env = "rc"' >> terraform.tfvars + env: + TFVARS_RC: ${{ secrets.TFVARS_RC }} + OAUTH_GITHUB: ${{ secrets.OAUTH_GITHUB }} + OAUTH_KAKAO: ${{ secrets.OAUTH_KAKAO }} + + - name: Terraform Init + working-directory: ./apps/infra/rc/codedang + run: terraform init -backend-config="bucket=codedang-tf-state-rc" + + - name: Terraform Plan + working-directory: ./apps/infra/rc/codedang + run: terraform plan -input=false -out=plan.out + + - name: Terraform Apply + working-directory: ./apps/infra/rc/codedang + run: terraform apply -input=false plan.out diff --git a/.github/workflows/rc-destroy-target.yml b/.github/workflows/rc-destroy-target.yml new file mode 100644 index 0000000000..8d1990353a --- /dev/null +++ b/.github/workflows/rc-destroy-target.yml @@ -0,0 +1,60 @@ +name: RC - Destroy - Target + +on: + workflow_dispatch: + inputs: + terraform_project: + description: 'Select Terraform Project to Destroy' + required: true + type: choice + options: + - 'network' + - 'storage' + - 'codedang' + +env: + AWS_REGION: ap-northeast-2 + ECS_CLUSTER: Codedang-Api + +permissions: # permissions to the job (for the OpenID Connection) + id-token: write + contents: read + +jobs: + rc-destroy-terraform-target-project: + name: RC - Destroy Terraform targeted Project + runs-on: ubuntu-latest + environment: production + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v4 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_DEPLOY_RC }} + aws-region: ${{ env.AWS_REGION }} + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.5.2 + + - name: Create Terraform variable file + working-directory: ./apps/infra/rc/${{ github.event.inputs.terraform_project }} + run: | + echo "$TFVARS_RC" >> terraform.tfvars + echo "$OAUTH_GITHUB" >> terraform.tfvars + echo "$OAUTH_KAKAO" >> terraform.tfvars + echo 'env = "rc"' >> terraform.tfvars + env: + TFVARS_RC: ${{ secrets.TFVARS_RC }} + OAUTH_GITHUB: ${{ secrets.OAUTH_GITHUB }} + OAUTH_KAKAO: ${{ secrets.OAUTH_KAKAO }} + + - name: Destroy + working-directory: ./apps/infra/rc/${{ github.event.inputs.terraform_project }} + run: | + terraform init -backend-config="bucket=codedang-tf-state-rc" + terraform destroy -auto-approve diff --git a/.github/workflows/rc-destroy.yml b/.github/workflows/rc-destroy.yml new file mode 100644 index 0000000000..eef921c579 --- /dev/null +++ b/.github/workflows/rc-destroy.yml @@ -0,0 +1,74 @@ +name: RC - destroy +#Except Terraform-Configuration Project + +on: + workflow_dispatch: + +env: + AWS_REGION: ap-northeast-2 + ECS_CLUSTER: Codedang-Api + +permissions: # permissions to the job (for the OpenID Connection) + id-token: write + contents: read + +jobs: + rc-destroy: + name: Destroy + runs-on: ubuntu-latest + environment: production + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v4 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_DEPLOY_RC }} + aws-region: ${{ env.AWS_REGION }} + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.5.2 + + - name: Create Terraform variable file (Codedang) + working-directory: ./apps/infra/rc/codedang + run: | + echo "$TFVARS_RC" >> terraform.tfvars + echo "$OAUTH_GITHUB" >> terraform.tfvars + echo "$OAUTH_KAKAO" >> terraform.tfvars + echo 'env = "rc"' >> terraform.tfvars + env: + TFVARS_RC: ${{ secrets.TFVARS_RC }} + OAUTH_GITHUB: ${{ secrets.OAUTH_GITHUB }} + OAUTH_KAKAO: ${{ secrets.OAUTH_KAKAO }} + + - name: Destroy Codedang + working-directory: ./apps/infra/rc/codedang + run: | + terraform init -backend-config="bucket=codedang-tf-state-rc" + terraform destroy -auto-approve + + - name: Create Terraform variable file (Storage) + working-directory: ./apps/infra/rc/storage + run: | + echo 'env = "rc"' >> terraform.tfvars + + - name: Destroy Storage + working-directory: ./apps/infra/rc/storage + run: | + terraform init -backend-config="bucket=codedang-tf-state-rc" + terraform destroy -auto-approve + + - name: Create Terraform variable file (Network) + working-directory: ./apps/infra/rc/network + run: | + echo 'env = "rc"' >> terraform.tfvars + + - name: Destroy Network + working-directory: ./apps/infra/rc/network + run: | + terraform init -backend-config="bucket=codedang-tf-state-rc" + terraform destroy -auto-approve diff --git a/.github/workflows/rc-init-config.yml b/.github/workflows/rc-init-config.yml new file mode 100644 index 0000000000..52504cd02f --- /dev/null +++ b/.github/workflows/rc-init-config.yml @@ -0,0 +1,50 @@ +name: RC - Init + +on: + workflow_dispatch: + +env: + AWS_REGION: ap-northeast-2 + ECS_CLUSTER: Codedang-Api + +permissions: # permissions to the job (for the OpenID Connection) + id-token: write + contents: read + +jobs: + rc-init-config: + name: RC - Init Config + runs-on: ubuntu-latest + environment: production + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v4 + + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_FOR_DEPLOY_RC }} + aws-region: ${{ env.AWS_REGION }} + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.5.2 + + - name: Create Terraform variable file + working-directory: ./apps/infra/rc/terraform-configuration + run: | + echo 'env = "rc"' >> terraform.tfvars + + - name: Terraform Init + working-directory: ./apps/infra/rc/terraform-configuration + run: terraform init -backend-config="bucket=codedang-tf-state-rc" + + - name: Terraform Plan + working-directory: ./apps/infra/rc/terraform-configuration + run: terraform plan -input=false -out=plan.out + + - name: Terraform Apply + working-directory: ./apps/infra/rc/terraform-configuration + run: terraform apply -input=false plan.out diff --git a/apps/infra/rc/codedang/cloudfront.tf b/apps/infra/rc/codedang/cloudfront.tf index ca256f1bd1..27e0993dcd 100644 --- a/apps/infra/rc/codedang/cloudfront.tf +++ b/apps/infra/rc/codedang/cloudfront.tf @@ -12,6 +12,7 @@ data "aws_cloudfront_origin_request_policy" "exclude_host_header" { resource "aws_cloudfront_distribution" "codedang" { origin { + #TODO : RC서버 Amplify 문제 해결 domain_name = var.env == "production" ? "amplify.codedang.com" : "main.d11kq2upsmcpi9.amplifyapp.com" origin_id = "frontend" # TODO: Add unique ID of Amplify