From 91957c40856d40c92adee17477ecab7f9d759397 Mon Sep 17 00:00:00 2001 From: Alexandre Henrique Afonso Campos Date: Sat, 5 Aug 2023 11:50:30 -0300 Subject: [PATCH] Add IAC part 1 (#100) * 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 iac deploy * Add default tags * Complete deployment instructions --- .github/workflows/backdeploy.yaml | 30 ++++++-- .github/workflows/iacdeploy.yaml | 32 +++++++++ .github/workflows/iactest.yaml | 34 +++++++++ iac/.gitignore | 1 + iac/.terraform.lock.hcl | 25 +++++++ iac/README.md | 49 +++++++++++++ iac/alb.tf | 68 ++++++++++++++++++ iac/batch.tf | 72 +++++++++++++++++++ iac/data-ssm.tf | 19 +++++ iac/ecr.tf | 35 +++++++++ iac/ecs.tf | 59 +++++++++++++++ iac/main.tf | 26 +++++++ iac/rds.tf | 18 +++++ iac/security-group.tf | 69 ++++++++++++++++++ iac/ssm-parameter.tf | 9 +++ iac/subnet.tf | 15 ++++ iac/templates/batch/statistics_cron.json.tpl | 47 ++++++++++++ iac/templates/ecr/expire-policy.json | 16 +++++ .../ecs/statistics_server_app.json.tpl | 53 ++++++++++++++ iac/templates/policies/assume-role-batch.json | 12 ++++ iac/templates/policies/assume-role-ec2.json | 12 ++++ iac/templates/policies/assume-role-ecs.json | 12 ++++ iac/variable.tf | 48 +++++++++++++ iac/vpc.tf | 2 + 24 files changed, 757 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/iacdeploy.yaml create mode 100644 .github/workflows/iactest.yaml create mode 100644 iac/.gitignore create mode 100644 iac/.terraform.lock.hcl create mode 100644 iac/README.md create mode 100644 iac/alb.tf create mode 100644 iac/batch.tf create mode 100644 iac/data-ssm.tf create mode 100644 iac/ecr.tf create mode 100644 iac/ecs.tf create mode 100644 iac/main.tf create mode 100644 iac/rds.tf create mode 100644 iac/security-group.tf create mode 100644 iac/ssm-parameter.tf create mode 100644 iac/subnet.tf create mode 100644 iac/templates/batch/statistics_cron.json.tpl create mode 100644 iac/templates/ecr/expire-policy.json create mode 100644 iac/templates/ecs/statistics_server_app.json.tpl create mode 100644 iac/templates/policies/assume-role-batch.json create mode 100644 iac/templates/policies/assume-role-ec2.json create mode 100644 iac/templates/policies/assume-role-ecs.json create mode 100644 iac/variable.tf create mode 100644 iac/vpc.tf diff --git a/.github/workflows/backdeploy.yaml b/.github/workflows/backdeploy.yaml index ca033a2b..7f918379 100644 --- a/.github/workflows/backdeploy.yaml +++ b/.github/workflows/backdeploy.yaml @@ -41,13 +41,31 @@ jobs: password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - - name: Build and push + - name: Build and push to ECR uses: docker/build-push-action@v2 - with: - context: ./server - file: ./server/Dockerfile - push: true - tags: thewca/statistics-server:latest + run: | + cd server + ./gradlew clean build --info -x test + + export STAGE=prod + GIT_HASH=$(git rev-parse --short HEAD) + + # Get value from ssm and export it + ECR_URL_PARAM=$(aws ssm get-parameter --name "/$STAGE/ecr/url/statistics_server") + ECR_URL=$(echo $ECR_URL_PARAM | jq -r '.Parameter.Value') + + # Before and after the bar + ECR_URL_ROOT="${ECR_URL%%/*}" + ECR_URL_SPEC="${ECR_URL##*/}" + + aws ecr get-login-password --region ${{ env.AWS_DEFAULT_REGION }} | docker login --username AWS --password-stdin $ECR_URL_ROOT + docker build -t $ECR_URL_SPEC . + + docker tag $ECR_URL_SPEC:latest $ECR_URL:latest + docker tag $ECR_URL_SPEC:latest $ECR_URL:$GIT_HASH + docker push $ECR_URL:latest + docker push $ECR_URL:$GIT_HASH + - name: Blue green deployment run: | export AWS_ACCESS_KEY_ID=${{ secrets.CI_CD_AWS_ACCESS_KEY_ID }} diff --git a/.github/workflows/iacdeploy.yaml b/.github/workflows/iacdeploy.yaml new file mode 100644 index 00000000..7fe1727b --- /dev/null +++ b/.github/workflows/iacdeploy.yaml @@ -0,0 +1,32 @@ +name: IAC Deploy + +on: + push: + branches: + - main + paths: + - "iac/**" + - ".github/workflows/iacdeploy.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 }} + +defaults: + run: + working-directory: iac + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: hashicorp/setup-terraform@v2 + - run: terraform init + - name: Select workspace and apply app + run: | + terraform workspace select $STAGE || terraform workspace new $STAGE + terraform apply --auto-approve diff --git a/.github/workflows/iactest.yaml b/.github/workflows/iactest.yaml new file mode 100644 index 00000000..ab2c18f4 --- /dev/null +++ b/.github/workflows/iactest.yaml @@ -0,0 +1,34 @@ +name: Test terraform + +env: + STAGE: prod + ENV: -prod + AWS_DEFAULT_REGION: ${{ env.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 }} + +on: + pull_request: + branches: + - main + paths: + - "iac/**" + - ".github/workflows/iactest.yaml" + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: hashicorp/setup-terraform@v2 + - name: Replace bucket name + run: | + sed -i "s|bucket = \"NON-EXISTING-BUCKET\"|bucket = \"${{ env.IAC_BUCKET_NAME }}\"|g" iac/main.tf + - run: terraform init + - name: Change workspace + run: | + terraform workspace select $STAGE || terraform workspace new $STAGE + - name: Plan + run: | + terraform plan -out tfapply diff --git a/iac/.gitignore b/iac/.gitignore new file mode 100644 index 00000000..1c99dc13 --- /dev/null +++ b/iac/.gitignore @@ -0,0 +1 @@ +.terraform/ diff --git a/iac/.terraform.lock.hcl b/iac/.terraform.lock.hcl new file mode 100644 index 00000000..c8f1951e --- /dev/null +++ b/iac/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.10.0" + constraints = "~> 5.0" + hashes = [ + "h1:ll2mC5mMF+Tm/+tmDQ6p6h3oAFpMSbZsA54STMZegwI=", + "zh:24f8b40ba25521ec809906623ce1387542f3da848952167bc960663583a7b2c7", + "zh:3c12afbda4e8ed44ab8315d16bbba4329ef3f18ffe3c0d5ea456dd05472fa610", + "zh:4da2de97535c7fb51ede8ef9b6bd45c790005aec36daac4317a6175d2ff632fd", + "zh:5631fd3c02c5abe5e51a73bd77ddeaaf97b2d508845ea03bc1e5955b52d94706", + "zh:5bdef27b4e5b2dcd0661125fcc1e70826d545903b1e19bb8d28d2a0c812468d5", + "zh:7b7f6b3e00ad4b7bfaa9872388f7b8014d8c9a1fe5c3f9f57865535865727633", + "zh:935f7a599a3f55f69052b096491262d59787625ce5d52f729080328e5088e823", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:a451a24f6675f8ad643a9b218cdb54c2af75a53d6a712daff46f64b81ec61032", + "zh:a5bcf820baefdc9f455222878f276a7f406a1092ac7b4c0cdbd6e588bff84847", + "zh:c9ab7b838a75bbcacc298658c1a04d1f0ee5935a928d821afcbe08c98cca7c5f", + "zh:d83855b6d66aaa03b1e66e03b7d0a4d1c9f992fce06f00011edde2a6ad6d91d6", + "zh:f1793e9a1e3ced98ca301ef1a294f46c06f77f6eb10f4d67ffef87ea60835421", + "zh:f366c99ddb16d75e07a687a60c015e8e2e0cdb593dea902385629571bd604859", + "zh:fb3ec60ea72144f480f495634c6d3e7a7638d7061a77c228a30768c1ae0b91f6", + ] +} diff --git a/iac/README.md b/iac/README.md new file mode 100644 index 00000000..0d8f6631 --- /dev/null +++ b/iac/README.md @@ -0,0 +1,49 @@ +# Statistics IAC + +This is the IAC for the statistics project, using terraform and AWS. + +## Requirements + +- Terraform +- AWS account + +## Setup + +- Create a bucket and replace its name in `iac/main.tf`. + +- Install [terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started) + +- Start terraform + + `terraform init` + +- Create or select new workspace + + `terraform workspace select prod || terraform workspace new prod` + +- Run plan + + `terraform plan` + +## Resources created manually + +To avoid the usage of variables in terraform (like tfvars), some resources are created manually and referenced here. You need to create them and run the project (or run when there are changes in the variables). + +```bash +export region=us-west-2 +export environment=prod +export app_id="SOME_APP_ID_HERE" +export write_user="USERNAME_HERE" +export write_password="STRONG_PASSWORD_HERE" +export read_user="USERNAME_HERE" +export read_password="ANOTHER_STRONG_PASSWORD_HERE" + +``` + +```bash +aws ssm put-parameter --name "/config/$environment/statistics/app/id" --value $app_id --overwrite --region $region --type String +aws ssm put-parameter --name "/config/$environment/statistics/dumped_db/write_user" --value $write_user --overwrite --region $region --type String +aws ssm put-parameter --name "/config/$environment/statistics/dumped_db/write_password" --value $write_password --overwrite --region $region --type String +aws ssm put-parameter --name "/config/$environment/statistics/dumped_db/read_user" --value $read_user --overwrite --region $region --type String +aws ssm put-parameter --name "/config/$environment/statistics/dumped_db/read_password" --value $read_password --overwrite --region $region --type String +``` diff --git a/iac/alb.tf b/iac/alb.tf new file mode 100644 index 00000000..0f7bab6f --- /dev/null +++ b/iac/alb.tf @@ -0,0 +1,68 @@ +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" +} + +resource "aws_alb_target_group" "statistics_server_target_group" { + name_prefix = "stattg" + port = var.default_tomcat_port + protocol = "HTTP" + vpc_id = aws_default_vpc.default.id + target_type = "ip" + + lifecycle { + create_before_destroy = true + } + + health_check { + healthy_threshold = "3" + interval = "30" + protocol = "HTTP" + matcher = "200" + timeout = "3" + path = "/actuator/health" + unhealthy_threshold = "2" + } +} + +resource "aws_alb_target_group" "statistics_server_target_group_blue_green" { + name_prefix = "stttg2" + port = var.default_tomcat_port + protocol = "HTTP" + vpc_id = aws_default_vpc.default.id + target_type = "ip" + + lifecycle { + create_before_destroy = true + } + + health_check { + healthy_threshold = "3" + interval = "30" + protocol = "HTTP" + matcher = "200" + timeout = "3" + path = "/actuator/health" + unhealthy_threshold = "2" + } +} + +data "aws_acm_certificate" "statistics_server_cetificate" { + domain = "statistics-api.worldcubeassociation.org" + statuses = ["ISSUED"] +} + +resource "aws_alb_listener" "statistics_server_https_listener" { + load_balancer_arn = aws_alb.statistics_server_load_balancer.arn + port = var.https_port + protocol = "HTTPS" + ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06" + certificate_arn = data.aws_acm_certificate.statistics_server_cetificate.arn + + default_action { + target_group_arn = aws_alb_target_group.statistics_server_target_group.id + type = "forward" + } +} diff --git a/iac/batch.tf b/iac/batch.tf new file mode 100644 index 00000000..44ace0c1 --- /dev/null +++ b/iac/batch.tf @@ -0,0 +1,72 @@ +resource "aws_iam_role" "ecs_instance_role" { + name = "ecs-instance-role-${terraform.workspace}" + + assume_role_policy = templatefile("${path.module}/templates/policies/assume-role-ec2.json", {}) +} + +resource "aws_iam_instance_profile" "ecs_instance_role" { + name = "ecs-instance-role-${terraform.workspace}" + role = aws_iam_role.ecs_instance_role.name +} + +resource "aws_iam_role" "statistics_cron_service_role" { + name = "statistics-cron-service-role-${terraform.workspace}" + + assume_role_policy = templatefile("${path.module}/templates/policies/assume-role-batch.json", {}) +} + +resource "aws_iam_role_policy_attachment" "statistics_cron_service_role" { + role = aws_iam_role.statistics_cron_service_role.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole" +} + +resource "aws_batch_compute_environment" "statistics_cron_compute_environment" { + type = "MANAGED" + compute_environment_name = "statistics-cron-compute-environment-${terraform.workspace}" + state = "ENABLED" + service_role = aws_iam_role.statistics_cron_service_role.arn + + compute_resources { + max_vcpus = 4 + + security_group_ids = [aws_security_group.all_out.id] + + subnets = [ + aws_default_subnet.default_az1.id, + aws_default_subnet.default_az2.id + ] + + type = "FARGATE" + } + + depends_on = [aws_iam_role_policy_attachment.statistics_cron_service_role] +} + +resource "aws_batch_job_queue" "statistics_cron_job_queue" { + name = "statistics-cron-job-queue-${terraform.workspace}" + state = "ENABLED" + priority = 1 + compute_environments = [aws_batch_compute_environment.statistics_cron_compute_environment.arn] +} + +resource "aws_batch_job_definition" "statistics_cron_job_definition" { + name = "statistics-cron-job-definition-${terraform.workspace}" + type = "container" + platform_capabilities = ["FARGATE"] + + container_properties = templatefile("./templates/batch/statistics_cron.json.tpl", { + image = "${aws_ecr_repository.statistics_cron.repository_url}:latest" + statistics_port = "8080" + db_port = "3306" + db_host = aws_db_instance.dumped_db.address + db_name = "wca_development" + 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 + }) +} + +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", {}) +} diff --git a/iac/data-ssm.tf b/iac/data-ssm.tf new file mode 100644 index 00000000..8915194e --- /dev/null +++ b/iac/data-ssm.tf @@ -0,0 +1,19 @@ +data "aws_ssm_parameter" "statistics_app_id" { + name = "/config/${terraform.workspace}/statistics/app/id" +} + +data "aws_ssm_parameter" "dumped_db_write_user" { + name = "/config/${terraform.workspace}/statistics/dumped_db/write_user" +} + +data "aws_ssm_parameter" "dumped_db_write_password" { + name = "/config/${terraform.workspace}/statistics/dumped_db/write_password" +} + +data "aws_ssm_parameter" "dumped_db_read_user" { + name = "/config/${terraform.workspace}/statistics/dumped_db/read_user" +} + +data "aws_ssm_parameter" "dumped_db_read_password" { + name = "/config/${terraform.workspace}/statistics/dumped_db/read_password" +} diff --git a/iac/ecr.tf b/iac/ecr.tf new file mode 100644 index 00000000..adb459c4 --- /dev/null +++ b/iac/ecr.tf @@ -0,0 +1,35 @@ +resource "aws_ecr_repository" "statistics_cron" { + name = "statistics-cron-${terraform.workspace}" + + image_scanning_configuration { + scan_on_push = true + } + + tags = { + (var.type) = var.type_ecr + } +} + +resource "aws_ecr_lifecycle_policy" "expire_images_statistics_cron" { + repository = aws_ecr_repository.statistics_cron.name + + policy = templatefile("./templates/ecr/expire-policy.json", {}) +} + +resource "aws_ecr_repository" "statistics_server" { + name = "statistics-server-${terraform.workspace}" + + image_scanning_configuration { + scan_on_push = true + } + + tags = { + (var.type) = var.type_ecr + } +} + +resource "aws_ecr_lifecycle_policy" "expire_images_statistics_server" { + repository = aws_ecr_repository.statistics_server.name + + policy = templatefile("./templates/ecr/expire-policy.json", {}) +} diff --git a/iac/ecs.tf b/iac/ecs.tf new file mode 100644 index 00000000..e36355f5 --- /dev/null +++ b/iac/ecs.tf @@ -0,0 +1,59 @@ +resource "aws_ecs_cluster" "statistics_server_cluster" { + name = "statistics-server-${terraform.workspace}" + + setting { + name = "containerInsights" + value = "enabled" + } +} + + +resource "aws_ecs_task_definition" "statistics_server_task_definition" { + family = "statistics-server-family-${terraform.workspace}" + network_mode = "awsvpc" + requires_compatibilities = ["FARGATE"] + cpu = 1024 // 1 vCPU = 1024 CPU units + memory = 2048 + execution_role_arn = aws_iam_role.ecs_task_execution_role.arn + + container_definitions = templatefile("./templates/ecs/statistics_server_app.json.tpl", { + app_image = aws_ecr_repository.statistics_server.repository_url + app_port = 8080 + fargate_cpu = 1024 + fargate_memory = 2048 + aws_region = var.aws_region + spring_profile = terraform.workspace + app_id = data.aws_ssm_parameter.statistics_app_id.value + db_port = "3306" + db_host = aws_db_instance.dumped_db.address + db_name = "wca_development" + db_username = data.aws_ssm_parameter.dumped_db_read_user.value + db_password = data.aws_ssm_parameter.dumped_db_read_password.value + }) +} + +resource "aws_ecs_service" "statistics_server_service" { + name = "statistics-server-service-${terraform.workspace}" + cluster = aws_ecs_cluster.statistics_server_cluster.id + task_definition = aws_ecs_task_definition.statistics_server_task_definition.arn + desired_count = 1 + launch_type = "FARGATE" + + network_configuration { + subnets = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] + security_groups = [aws_security_group.http_security_group.id] + assign_public_ip = true + } + + load_balancer { + target_group_arn = aws_alb_target_group.statistics_server_target_group.id + container_name = "statistics-server-app" + container_port = var.default_tomcat_port + } + + deployment_controller { + type = "CODE_DEPLOY" + } + + # depends_on = [aws_iam_role_policy_attachment.ecs_task_execution_role] +} diff --git a/iac/main.tf b/iac/main.tf new file mode 100644 index 00000000..d8a67a19 --- /dev/null +++ b/iac/main.tf @@ -0,0 +1,26 @@ +terraform { + backend "s3" { + bucket = "NON-EXISTING-BUCKET" + key = "statistics-standalone-iac" + region = "us-west-2" + } +} + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + +provider "aws" { + region = var.aws_region + + default_tags { + tags = { + Reason = "statistics" + } + } +} diff --git a/iac/rds.tf b/iac/rds.tf new file mode 100644 index 00000000..86a2723d --- /dev/null +++ b/iac/rds.tf @@ -0,0 +1,18 @@ +resource "aws_db_instance" "dumped_db" { + identifier = "dumped-db-${terraform.workspace}" + allocated_storage = "100" + engine = "mysql" + engine_version = "8.0.33" + storage_type = "gp2" + instance_class = "db.t3.small" + db_name = "dumped_db" + username = data.aws_ssm_parameter.dumped_db_write_user.value + password = data.aws_ssm_parameter.dumped_db_write_password.value + port = var.default_mysql_port + parameter_group_name = "default.mysql8.0" + skip_final_snapshot = true + publicly_accessible = true + vpc_security_group_ids = [aws_security_group.mysql_default_port.id, aws_security_group.all_out.id] + apply_immediately = true +} + diff --git a/iac/security-group.tf b/iac/security-group.tf new file mode 100644 index 00000000..d9eb23c1 --- /dev/null +++ b/iac/security-group.tf @@ -0,0 +1,69 @@ +resource "aws_security_group" "all_out" { + name = "all-out-${terraform.workspace}}" + description = "Allow HTTP" + vpc_id = aws_default_vpc.default.id + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } +} + +resource "aws_security_group" "mysql_default_port" { + name = "default-mysql-${terraform.workspace}}" + description = "Default mysql" + vpc_id = aws_default_vpc.default.id + + ingress { + description = "HTTP" + from_port = var.default_mysql_port + to_port = var.default_mysql_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } +} + +resource "aws_security_group" "http_security_group" { + name = "http-sg-statistics-${terraform.workspace}" + description = "Allow HTTP" + vpc_id = aws_default_vpc.default.id + + ingress { + description = "HTTP" + from_port = var.http_port + to_port = var.http_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + description = "HTTPS" + from_port = var.https_port + to_port = var.https_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + tags = { + (var.type) = var.type_sg + } +} diff --git a/iac/ssm-parameter.tf b/iac/ssm-parameter.tf new file mode 100644 index 00000000..e5884813 --- /dev/null +++ b/iac/ssm-parameter.tf @@ -0,0 +1,9 @@ +resource "aws_ssm_parameter" "statistics_server_app_ecr_url" { + name = "/${terraform.workspace}/ecr/url/statistics_server" + type = "String" + value = aws_ecr_repository.statistics_server.repository_url + + tags = { + "Type" = var.type_ssm + } +} diff --git a/iac/subnet.tf b/iac/subnet.tf new file mode 100644 index 00000000..810a0fcb --- /dev/null +++ b/iac/subnet.tf @@ -0,0 +1,15 @@ +resource "aws_default_subnet" "default_az1" { + availability_zone = "${var.aws_region}a" + + tags = { + (var.type) = var.type_subnet + } +} + +resource "aws_default_subnet" "default_az2" { + availability_zone = "${var.aws_region}b" + + tags = { + (var.type) = var.type_subnet + } +} diff --git a/iac/templates/batch/statistics_cron.json.tpl b/iac/templates/batch/statistics_cron.json.tpl new file mode 100644 index 00000000..9c4a70d6 --- /dev/null +++ b/iac/templates/batch/statistics_cron.json.tpl @@ -0,0 +1,47 @@ +{ + "command": [], + "image": "${image}", + "environment": [ + { + "name": "STATISTICS_PORT", + "value": "${statistics_port}" + }, + { + "name": "DB_HOST", + "value": "${db_host}" + }, + { + "name": "DB_DATABASE", + "value": "${db_name}" + }, + { + "name": "DB_USERNAME", + "value": "${db_username}" + }, + { + "name": "DB_PASSWORD", + "value": "${db_password}" + }, + { + "name": "DB_PORT", + "value": "${db_port}" + } + ], + "fargatePlatformConfiguration": { + "platformVersion": "LATEST" + }, + "networkConfiguration": { + "assignPublicIp": "ENABLED" + }, + "resourceRequirements": [ + { + "type": "VCPU", + "value": "4" + }, + { + "type": "MEMORY", + "value": "8192" + } + ], + "executionRoleArn": "${execution_role}" +} \ No newline at end of file diff --git a/iac/templates/ecr/expire-policy.json b/iac/templates/ecr/expire-policy.json new file mode 100644 index 00000000..c375dc64 --- /dev/null +++ b/iac/templates/ecr/expire-policy.json @@ -0,0 +1,16 @@ +{ + "rules": [ + { + "rulePriority": 1, + "description": "Keep last 2 images", + "selection": { + "tagStatus": "any", + "countType": "imageCountMoreThan", + "countNumber": 2 + }, + "action": { + "type": "expire" + } + } + ] +} diff --git a/iac/templates/ecs/statistics_server_app.json.tpl b/iac/templates/ecs/statistics_server_app.json.tpl new file mode 100644 index 00000000..201aab01 --- /dev/null +++ b/iac/templates/ecs/statistics_server_app.json.tpl @@ -0,0 +1,53 @@ +[ + { + "name": "statistics-server-app", + "image": "${app_image}:latest", + "cpu": ${fargate_cpu}, + "memory": ${fargate_memory}, + "networkMode": "awsvpc", + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-group": "/ecs/statistics-server-app", + "awslogs-region": "${aws_region}", + "awslogs-stream-prefix": "ecs" + } + }, + "portMappings": [ + { + "containerPort": ${app_port}, + "hostPort": ${app_port} + } + ], + "environment": [ + { + "name": "APP_ID", + "value": "${app_id}" + }, + { + "name": "DB_USERNAME", + "value": "${db_username}" + }, + { + "name": "DB_PORT", + "value": "${db_port}" + }, + { + "name": "SPRING_PROFILES_ACTIVE", + "value": "${spring_profile}" + }, + { + "name": "DB_HOST", + "value": "${db_host}" + }, + { + "name": "DB_DATABASE", + "value": "${db_name}" + }, + { + "name": "DB_PASSWORD", + "value": "${db_password}" + } + ] + } +] \ No newline at end of file diff --git a/iac/templates/policies/assume-role-batch.json b/iac/templates/policies/assume-role-batch.json new file mode 100644 index 00000000..79641815 --- /dev/null +++ b/iac/templates/policies/assume-role-batch.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "batch.amazonaws.com" + } + } + ] +} diff --git a/iac/templates/policies/assume-role-ec2.json b/iac/templates/policies/assume-role-ec2.json new file mode 100644 index 00000000..d84df683 --- /dev/null +++ b/iac/templates/policies/assume-role-ec2.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ] +} diff --git a/iac/templates/policies/assume-role-ecs.json b/iac/templates/policies/assume-role-ecs.json new file mode 100644 index 00000000..2eb718b6 --- /dev/null +++ b/iac/templates/policies/assume-role-ecs.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ] +} diff --git a/iac/variable.tf b/iac/variable.tf new file mode 100644 index 00000000..0f0f7da4 --- /dev/null +++ b/iac/variable.tf @@ -0,0 +1,48 @@ +variable "environment_to_suffix_map" { + type = map(any) + default = { + dev = "-dev" + staging = "-stg" + prod = "" + } +} + +variable "aws_region" { + default = "us-west-2" +} + +variable "type" { + default = "Type" +} + +variable "type_subnet" { + default = "Subnet" +} + +variable "type_ecr" { + default = "ECR" +} + +variable "type_ssm" { + default = "SSM" +} + +variable "type_sg" { + default = "SG" +} + +variable "default_mysql_port" { + default = 3306 +} + +variable "http_port" { + default = 80 +} + +variable "https_port" { + default = 443 +} + +variable "default_tomcat_port" { + default = 8080 +} diff --git a/iac/vpc.tf b/iac/vpc.tf new file mode 100644 index 00000000..ef3ae50e --- /dev/null +++ b/iac/vpc.tf @@ -0,0 +1,2 @@ +resource "aws_default_vpc" "default" { +}