Skip to content

Commit

Permalink
Add IAC (#99)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
campos20 authored Oct 14, 2023
1 parent 44fed15 commit 3577260
Show file tree
Hide file tree
Showing 18 changed files with 291 additions and 66 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/iacdeploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
36 changes: 0 additions & 36 deletions .github/workflows/iactest.yaml

This file was deleted.

1 change: 1 addition & 0 deletions iac/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.terraform/
app-spec/
19 changes: 19 additions & 0 deletions iac/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions iac/alb.tf
Original file line number Diff line number Diff line change
@@ -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" {
Expand Down
22 changes: 21 additions & 1 deletion iac/batch.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 = "*"
}
]
})
}
}
99 changes: 99 additions & 0 deletions iac/code-deploy.tf
Original file line number Diff line number Diff line change
@@ -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 = <<EOF
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "${replace(aws_ecs_task_definition.statistics_server_task_definition.arn, "/:[0-9]+$/", "")}"
LoadBalancerInfo:
ContainerName: "${var.container_name}"
ContainerPort: "${var.default_tomcat_port}"
PlatformVersion: "LATEST"
EOF
filename = "${var.app_spec_folder}/statistics-spec-${terraform.workspace}.yaml"
}

resource "aws_s3_object" "api_app_spec_file" {
bucket = var.bucket_name
key = local_file.statistics_app_spec.filename
source = local_file.statistics_app_spec.filename

etag = md5(local_file.statistics_app_spec.content)
}
19 changes: 9 additions & 10 deletions iac/ecs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@ 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
cpu = var.statistics_fargate_cpu
memory = var.statistics_fargate_memory
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
container_name = var.container_name
app_port = var.default_tomcat_port
fargate_cpu = var.statistics_fargate_cpu
fargate_memory = var.statistics_fargate_memory
aws_region = var.aws_region
spring_profile = terraform.workspace
app_id = data.aws_ssm_parameter.statistics_app_id.value
db_port = "3306"
db_port = var.default_mysql_port
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_read_user.value
db_password = data.aws_ssm_parameter.dumped_db_read_password.value
})
Expand All @@ -41,7 +42,7 @@ resource "aws_ecs_service" "statistics_server_service" {

network_configuration {
subnets = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id]
security_groups = [aws_security_group.http_security_group.id]
security_groups = [aws_security_group.http_security_group.id, aws_security_group.allow_tomcat.id]
assign_public_ip = true
}

Expand All @@ -54,6 +55,4 @@ resource "aws_ecs_service" "statistics_server_service" {
deployment_controller {
type = "CODE_DEPLOY"
}

# depends_on = [aws_iam_role_policy_attachment.ecs_task_execution_role]
}
42 changes: 42 additions & 0 deletions iac/eventbridge.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
resource "aws_cloudwatch_event_rule" "statistics_cron" {
name = "statistics-cron-${terraform.workspace}"
description = "Statistics cron"
schedule_expression = "cron(0 5 ? * TUE,FRI *)" # Tuesday, Friday. Kind of before competitions and after results posted
}

resource "aws_cloudwatch_event_target" "statistics_cron" {
rule = aws_cloudwatch_event_rule.statistics_cron.name
target_id = "SubmitStatisticsJob"
arn = aws_batch_job_queue.statistics_cron_job_queue.arn
role_arn = aws_iam_role.event_bus_invoke_remote_event_bus.arn
batch_target {
job_definition = aws_batch_job_definition.statistics_cron_job_definition.arn
job_name = "statistics-cron-${terraform.workspace}"
}
}

resource "aws_iam_role" "event_bus_invoke_remote_event_bus" {
name = "event-bus-statistics-${terraform.workspace}"
assume_role_policy = templatefile("${path.module}/templates/policies/assume-role-events.json", {})
}

data "aws_iam_policy_document" "event_bus_invoke_remote_event_bus" {
statement {
effect = "Allow"
actions = ["batch:SubmitJob"]
resources = [
aws_batch_job_definition.statistics_cron_job_definition.arn,
aws_batch_job_queue.statistics_cron_job_queue.arn
]
}
}

resource "aws_iam_policy" "event_bus_invoke_remote_event_bus" {
name = "event-bus-invoke-statistics-${terraform.workspace}"
policy = data.aws_iam_policy_document.event_bus_invoke_remote_event_bus.json
}

resource "aws_iam_role_policy_attachment" "event_bus_invoke_remote_event_bus" {
role = aws_iam_role.event_bus_invoke_remote_event_bus.name
policy_arn = aws_iam_policy.event_bus_invoke_remote_event_bus.arn
}
4 changes: 4 additions & 0 deletions iac/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ terraform {
}
}

variable "bucket_name" {
default = "NON-EXISTING-BUCKET"
}

terraform {
required_providers {
aws = {
Expand Down
3 changes: 3 additions & 0 deletions iac/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "access_url" {
value = aws_alb.statistics_server_load_balancer.dns_name
}
2 changes: 1 addition & 1 deletion iac/rds.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ resource "aws_db_instance" "dumped_db" {
engine = "mysql"
engine_version = "8.0.33"
storage_type = "gp2"
instance_class = "db.t3.small"
instance_class = "db.t3.medium"
db_name = "dumped_db"
username = data.aws_ssm_parameter.dumped_db_write_user.value
password = data.aws_ssm_parameter.dumped_db_write_password.value
Expand Down
22 changes: 22 additions & 0 deletions iac/security-group.tf
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,25 @@ resource "aws_security_group" "http_security_group" {
(var.type) = var.type_sg
}
}

resource "aws_security_group" "allow_tomcat" {
name = "default-tomcat-${terraform.workspace}}"
description = "Default tomcat"
vpc_id = aws_default_vpc.default.id

ingress {
description = "HTTP"
from_port = var.default_tomcat_port
to_port = var.default_tomcat_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"]
}
}
6 changes: 3 additions & 3 deletions iac/templates/ecs/statistics_server_app.json.tpl
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[
{
"name": "statistics-server-app",
"image": "${app_image}:latest",
"name": "${container_name}",
"image": "${app_image}",
"cpu": ${fargate_cpu},
"memory": ${fargate_memory},
"networkMode": "awsvpc",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/statistics-server-app",
"awslogs-group": "/ecs/${container_name}",
"awslogs-region": "${aws_region}",
"awslogs-stream-prefix": "ecs"
}
Expand Down
13 changes: 13 additions & 0 deletions iac/templates/policies/assume-role-code-deploy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "codedeploy.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Loading

0 comments on commit 3577260

Please sign in to comment.