From 35772606d7c91a549ac290cef294b3f6eff0f616 Mon Sep 17 00:00:00 2001 From: Alexandre Henrique Afonso Campos Date: Sat, 14 Oct 2023 16:50:23 -0300 Subject: [PATCH] Add IAC (#99) * Add iac folder * Generate terraform lock file and add batch role * Add compute resources for batch * Add dumped db * Add instructions about manual resources in README * Add terraform plan as iac test * Add alb and ecs * Add ECR parameter * Add task role arn * Add more variables, add tomcat as allowed port in alb * Change instance class from small to medium * Fix security group in ecs and make the task finally available * Remove iac test as it will fail for forks * Add variable for bucket * Add code deploy * Add some permissions for code dpeloy * Add event bridge * Add output url * Put back ALB for statistics using https --- .github/workflows/iacdeploy.yaml | 2 +- .github/workflows/iactest.yaml | 36 ------- iac/.gitignore | 1 + iac/.terraform.lock.hcl | 19 ++++ iac/alb.tf | 8 +- iac/batch.tf | 22 ++++- iac/code-deploy.tf | 99 +++++++++++++++++++ iac/ecs.tf | 19 ++-- iac/eventbridge.tf | 42 ++++++++ iac/main.tf | 4 + iac/output.tf | 3 + iac/rds.tf | 2 +- iac/security-group.tf | 22 +++++ .../ecs/statistics_server_app.json.tpl | 6 +- .../policies/assume-role-code-deploy.json | 13 +++ .../policies/assume-role-events.json | 12 +++ .../policies/code-deploy-statistics.json | 15 +++ iac/variable.tf | 32 ++++-- 18 files changed, 291 insertions(+), 66 deletions(-) delete mode 100644 .github/workflows/iactest.yaml create mode 100644 iac/code-deploy.tf create mode 100644 iac/eventbridge.tf create mode 100644 iac/output.tf create mode 100644 iac/templates/policies/assume-role-code-deploy.json create mode 100644 iac/templates/policies/assume-role-events.json create mode 100644 iac/templates/policies/code-deploy-statistics.json diff --git a/.github/workflows/iacdeploy.yaml b/.github/workflows/iacdeploy.yaml index 7f1672f3..5d8054a9 100644 --- a/.github/workflows/iacdeploy.yaml +++ b/.github/workflows/iacdeploy.yaml @@ -28,7 +28,7 @@ jobs: - uses: hashicorp/setup-terraform@v2 - name: Replace bucket name run: | - sed -i "s|bucket = \"NON-EXISTING-BUCKET\"|bucket = \"$IAC_BUCKET_NAME\"|g" main.tf + sed -i "s|t = \"NON-EXISTING-BUCKET\"|t = \"$IAC_BUCKET_NAME\"|g" main.tf - run: terraform init - name: Select workspace and apply app run: | diff --git a/.github/workflows/iactest.yaml b/.github/workflows/iactest.yaml deleted file mode 100644 index c425b413..00000000 --- a/.github/workflows/iactest.yaml +++ /dev/null @@ -1,36 +0,0 @@ -name: Test terraform - -on: - pull_request: - branches: - - main - paths: - - "iac/**" - - ".github/workflows/iactest.yaml" - -env: - STAGE: prod - AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} - AWS_ACCESS_KEY_ID: ${{ secrets.CI_CD_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_CD_AWS_SECRET_ACCESS_KEY }} - IAC_BUCKET_NAME: ${{ vars.IAC_BUCKET_NAME }} - -defaults: - run: - working-directory: iac - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - uses: hashicorp/setup-terraform@v2 - - name: Replace bucket name - run: | - sed -i "s|bucket = \"NON-EXISTING-BUCKET\"|bucket = \"$IAC_BUCKET_NAME\"|g" main.tf - - run: terraform init - - name: Plan - run: | - terraform workspace select $STAGE || terraform workspace new $STAGE - terraform plan -out tfapply diff --git a/iac/.gitignore b/iac/.gitignore index 1c99dc13..c0f72210 100644 --- a/iac/.gitignore +++ b/iac/.gitignore @@ -1 +1,2 @@ .terraform/ +app-spec/ diff --git a/iac/.terraform.lock.hcl b/iac/.terraform.lock.hcl index c8f1951e..e5f8a33a 100644 --- a/iac/.terraform.lock.hcl +++ b/iac/.terraform.lock.hcl @@ -23,3 +23,22 @@ provider "registry.terraform.io/hashicorp/aws" { "zh:fb3ec60ea72144f480f495634c6d3e7a7638d7061a77c228a30768c1ae0b91f6", ] } + +provider "registry.terraform.io/hashicorp/local" { + version = "2.4.0" + hashes = [ + "h1:ZUEYUmm2t4vxwzxy1BvN1wL6SDWrDxfH7pxtzX8c6d0=", + "zh:53604cd29cb92538668fe09565c739358dc53ca56f9f11312b9d7de81e48fab9", + "zh:66a46e9c508716a1c98efbf793092f03d50049fa4a83cd6b2251e9a06aca2acf", + "zh:70a6f6a852dd83768d0778ce9817d81d4b3f073fab8fa570bff92dcb0824f732", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:82a803f2f484c8b766e2e9c32343e9c89b91997b9f8d2697f9f3837f62926b35", + "zh:9708a4e40d6cc4b8afd1352e5186e6e1502f6ae599867c120967aebe9d90ed04", + "zh:973f65ce0d67c585f4ec250c1e634c9b22d9c4288b484ee2a871d7fa1e317406", + "zh:c8fa0f98f9316e4cfef082aa9b785ba16e36ff754d6aba8b456dab9500e671c6", + "zh:cfa5342a5f5188b20db246c73ac823918c189468e1382cb3c48a9c0c08fc5bf7", + "zh:e0e2b477c7e899c63b06b38cd8684a893d834d6d0b5e9b033cedc06dd7ffe9e2", + "zh:f62d7d05ea1ee566f732505200ab38d94315a4add27947a60afa29860822d3fc", + "zh:fa7ce69dde358e172bd719014ad637634bbdabc49363104f4fca759b4b73f2ce", + ] +} diff --git a/iac/alb.tf b/iac/alb.tf index 0f7bab6f..d09342d8 100644 --- a/iac/alb.tf +++ b/iac/alb.tf @@ -1,8 +1,8 @@ resource "aws_alb" "statistics_server_load_balancer" { - name = "statistics-server-alb-${terraform.workspace}" - subnets = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] - security_groups = [aws_security_group.http_security_group.id] - load_balancer_type = "application" + name = "statistics-server-alb-${terraform.workspace}" + subnets = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] + security_groups = [aws_security_group.http_security_group.id, aws_security_group.allow_tomcat.id] + idle_timeout = 300 } resource "aws_alb_target_group" "statistics_server_target_group" { diff --git a/iac/batch.tf b/iac/batch.tf index 44ace0c1..f701e6b8 100644 --- a/iac/batch.tf +++ b/iac/batch.tf @@ -59,7 +59,7 @@ resource "aws_batch_job_definition" "statistics_cron_job_definition" { statistics_port = "8080" db_port = "3306" db_host = aws_db_instance.dumped_db.address - db_name = "wca_development" + db_name = var.dumped_db_name db_username = data.aws_ssm_parameter.dumped_db_write_user.value db_password = data.aws_ssm_parameter.dumped_db_write_password.value execution_role = aws_iam_role.ecs_task_execution_role.arn @@ -69,4 +69,24 @@ resource "aws_batch_job_definition" "statistics_cron_job_definition" { resource "aws_iam_role" "ecs_task_execution_role" { name = "ecs-task-execution-role-${terraform.workspace}" assume_role_policy = templatefile("${path.module}/templates/policies/assume-role-ecs.json", {}) + + inline_policy { + name = "statistics-task-execution-role-policy-${terraform.workspace}" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = ["logs:*"] + Effect = "Allow" + Resource = "*" + }, + { + Action = ["ecr:*"] + Effect = "Allow" + Resource = "*" + } + ] + }) + } } diff --git a/iac/code-deploy.tf b/iac/code-deploy.tf new file mode 100644 index 00000000..6c2dd940 --- /dev/null +++ b/iac/code-deploy.tf @@ -0,0 +1,99 @@ +resource "aws_iam_role" "statistics_server_code_deploy_role" { + name = "statistics-server-code-deploy-role-${terraform.workspace}" + + inline_policy { + name = "statistics-inline-cd-${terraform.workspace}" + policy = templatefile("${path.module}/templates/policies/code-deploy-statistics.json", { + bucket_name = var.bucket_name + aws_region = var.aws_region + app_spec_folder = var.app_spec_folder + cluster_name = aws_ecs_cluster.statistics_server_cluster.name + service_name = aws_ecs_service.statistics_server_service.name + }) + } + + assume_role_policy = templatefile("${path.module}/templates/policies/assume-role-code-deploy.json", {}) +} + +resource "aws_iam_role_policy_attachment" "statistics_server_code_deploy_role" { + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole" + role = aws_iam_role.statistics_server_code_deploy_role.name +} + +resource "aws_codedeploy_app" "statistics_server_code_deploy_app" { + name = "statistics-server-code-deploy-app-${terraform.workspace}" + compute_platform = "ECS" +} + +resource "aws_codedeploy_deployment_group" "statistics_server_code_deployment_group" { + app_name = aws_codedeploy_app.statistics_server_code_deploy_app.name + deployment_config_name = "CodeDeployDefault.ECSAllAtOnce" + deployment_group_name = "statistics-server-code-deployment-group-${terraform.workspace}" + service_role_arn = aws_iam_role.statistics_server_code_deploy_role.arn + + auto_rollback_configuration { + enabled = true + events = ["DEPLOYMENT_FAILURE"] + } + + blue_green_deployment_config { + deployment_ready_option { + action_on_timeout = "CONTINUE_DEPLOYMENT" + } + + terminate_blue_instances_on_deployment_success { + action = "TERMINATE" + termination_wait_time_in_minutes = 5 + } + } + + deployment_style { + deployment_option = "WITH_TRAFFIC_CONTROL" + deployment_type = "BLUE_GREEN" + } + + ecs_service { + cluster_name = aws_ecs_cluster.statistics_server_cluster.name + service_name = aws_ecs_service.statistics_server_service.name + } + + load_balancer_info { + target_group_pair_info { + prod_traffic_route { + listener_arns = [aws_alb_listener.statistics_server_https_listener.arn] + } + + target_group { + name = aws_alb_target_group.statistics_server_target_group.name + } + + target_group { + name = aws_alb_target_group.statistics_server_target_group_blue_green.name + } + } + } +} + +resource "local_file" "statistics_app_spec" { + content = <