Skip to content

Commit 76fb26e

Browse files
committed
feat: full terra
1 parent 1565f2f commit 76fb26e

File tree

11 files changed

+735
-11
lines changed

11 files changed

+735
-11
lines changed

.env

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
# project config
22
PROJECT_NAME_PREFIX="poc2-terraform-node-hw"
33
AWS_REGION="us-east-1"
4+
APP_PORT="3011"
5+
HEALTH_CHECK_PATH="/"
46

57
# AWS tf infra output names
68
S3_BUCKET_OUTPUT_NAME="s3_bucket_name"
79
DYNAMODB_TABLE_OUTPUT_NAME="dynamodb_lock_table_name"
10+
LOG_RETENTION_DAYS_IN_CLOUDWATCH="3"
11+
FARGATE_CPU="1024"
12+
FARGATE_MEMORY="2048"
13+
TASK_DESIRED_COUNT="3"
14+
815

916
# ALB config
1017
# MIN_NUM_INSTANCES=1

.github/workflows/deploy-to-ecr.yml

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
env:
99
AWS_REGION: ${{ secrets.AWS_REGION }}
1010
AWS_IAM_ROLE_ARN: ${{ secrets.AWS_IAM_ROLE_ARN }}
11-
TERRAFORM_DIR: ./01-tf
11+
TERRAFORM_DIR: ${{ vars.TERRAFORM_DIR }}
1212
TERRAFORM_VERSION: '1.12.0'
1313

1414
jobs:
@@ -17,7 +17,7 @@ jobs:
1717
runs-on: ubuntu-latest
1818
permissions:
1919
contents: read
20-
id-token: write
20+
id-token: write # Required for OIDC with AWS
2121

2222
steps:
2323
- name: Checkout code
@@ -39,27 +39,44 @@ jobs:
3939
run: terraform init -input=false
4040
working-directory: ${{ env.TERRAFORM_DIR }}
4141

42-
- name: Terraform Apply
43-
id: apply
42+
# First Apply: Create ECR and other infrastructure
43+
- name: Terraform Apply (ECR and initial setup)
44+
id: apply_infra
4445
run: terraform apply -auto-approve -input=false
4546
working-directory: ${{ env.TERRAFORM_DIR }}
4647

47-
- name: Get ECR Repository URL
48-
id: get_ecr_url
49-
run: echo "ECR_REPOSITORY_URL=$(terraform output -raw ecr_repository_url)" >> $GITHUB_ENV
48+
- name: Get ECR Details from Terraform Output
49+
id: get_ecr_details
50+
run: |
51+
ECR_FULL_REPO_URL=$(terraform output -raw ecr_repository_url)
52+
ECR_REGISTRY=$(echo "$ECR_FULL_REPO_URL" | cut -d'/' -f1)
53+
echo "ECR_REGISTRY=$ECR_REGISTRY" >> $GITHUB_ENV
5054
working-directory: ${{ env.TERRAFORM_DIR }}
5155

5256
- name: Login to Amazon ECR
5357
id: login-ecr
5458
uses: docker/login-action@v3
5559
with:
56-
registry: ${{ env.ECR_REPOSITORY_URL }}
60+
registry: ${{ env.ECR_REGISTRY }} # Use the registry extracted
5761

5862
- name: Build, tag, and push image to Amazon ECR
5963
id: build-image
64+
env:
65+
ECR_REPOSITORY_URL: ${{ env.ECR_REPOSITORY_URL }}
66+
IMAGE_TAG: ${{ github.sha }}
6067
uses: docker/build-push-action@v5
6168
with:
6269
context: .
6370
file: ./Dockerfile
6471
push: true
65-
tags: ${{ env.ECR_REPOSITORY_URL }}:latest
72+
tags: | # Allow multiple tags
73+
${{ env.ECR_REPOSITORY_URL }}:${{ env.IMAGE_TAG }}
74+
${{ env.ECR_REPOSITORY_URL }}:latest
75+
76+
# Second Apply: Update ECS with new image
77+
- name: Terraform Apply (Update ECS with new image)
78+
id: apply_ecs_update
79+
env:
80+
TF_VAR_app_image_uri: '${{ env.ECR_REPOSITORY_URL }}:${{ github.sha }}'
81+
run: terraform apply -auto-approve -input=false
82+
working-directory: ${{ env.TERRAFORM_DIR }}

01-tf/alb.tf

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
##################################################
2+
## Application Load Balancer (ALB) & Target Group
3+
##################################################
4+
5+
# --- Target Group (type ip) ---
6+
resource "aws_lb_target_group" "app_tg" {
7+
name = "${var.project_name_prefix}-app-tg"
8+
port = var.app_port
9+
protocol = "HTTP"
10+
vpc_id = aws_vpc.main.id
11+
target_type = "ip"
12+
13+
health_check {
14+
enabled = true
15+
interval = 30
16+
path = var.health_check_path
17+
port = "traffic-port"
18+
protocol = "HTTP"
19+
timeout = 5
20+
healthy_threshold = 3
21+
unhealthy_threshold = 3
22+
matcher = "200"
23+
}
24+
25+
tags = merge(
26+
var.common_tags,
27+
{
28+
Name = "${var.project_name_prefix}-app-tg"
29+
}
30+
)
31+
}
32+
33+
# --- Application Load Balancer ---
34+
resource "aws_lb" "app_alb" {
35+
name = "${var.project_name_prefix}-alb"
36+
internal = false
37+
load_balancer_type = "application"
38+
security_groups = [aws_security_group.alb_sg.id]
39+
# The ALB is deployed in public subnets to be accessible
40+
subnets = aws_subnet.public[*].id
41+
42+
# ! Important
43+
# ! Change to 'true' in production
44+
enable_deletion_protection = false
45+
46+
tags = merge(
47+
var.common_tags,
48+
{
49+
Name = "${var.project_name_prefix}-alb"
50+
}
51+
)
52+
}
53+
54+
# --- Listener of the ALB (HTTP:80) ---
55+
resource "aws_lb_listener" "http_listener" {
56+
load_balancer_arn = aws_lb.app_alb.arn
57+
port = "80"
58+
protocol = "HTTP"
59+
60+
default_action {
61+
type = "forward"
62+
target_group_arn = aws_lb_target_group.app_tg.arn
63+
}
64+
}

01-tf/auto_generated_variables.tf

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,61 @@ variable "project_name_prefix" {
1313
type = string
1414
default = "poc2-terraform-node-hw"
1515
}
16+
17+
variable "common_tags" {
18+
description = "Tags to be applied to all resources"
19+
type = map(string)
20+
default = {
21+
Project = "poc2-terraform-node-hw"
22+
Terraform = "true"
23+
Environment = "dev"
24+
}
25+
}
26+
27+
variable "vpc_cidr" {
28+
description = "CIDR block for the VPC"
29+
type = string
30+
default = "10.0.0.0/16"
31+
}
32+
33+
variable "app_port" {
34+
description = "Port on which the application inside the container listens"
35+
type = number
36+
default = "3011"
37+
}
38+
39+
variable "health_check_path" {
40+
description = "Path to be used for health checks"
41+
type = string
42+
default = "/"
43+
}
44+
45+
variable "log_retention_days" {
46+
description = "Number of days to retain logs in CloudWatch"
47+
type = number
48+
default = "3"
49+
}
50+
51+
variable "fargate_cpu" {
52+
description = "Number of vCPUs for the Fargate task"
53+
type = string
54+
default = "1024"
55+
}
56+
57+
variable "fargate_memory" {
58+
description = "Amount of memory in MiB for the Fargate task"
59+
type = string
60+
default = "2048"
61+
}
62+
63+
variable "app_image_uri" {
64+
description = "The full URI of the Docker image in ECR"
65+
type = string
66+
default = "nginx:latest"
67+
}
68+
69+
variable "task_desired_count" {
70+
description = "Number of desired tasks to run"
71+
type = number
72+
default = "3"
73+
}

01-tf/ecs-cluster.tf

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
##################################################
2+
## ECS Cluster Fargate
3+
##################################################
4+
5+
resource "aws_ecs_cluster" "main_cluster" {
6+
name = "${var.project_name_prefix}-cluster-fargate"
7+
8+
setting {
9+
name = "containerInsights"
10+
value = "disabled"
11+
}
12+
13+
tags = merge(
14+
var.common_tags,
15+
{
16+
Name = "${var.project_name_prefix}-cluster-fargate"
17+
}
18+
)
19+
}
20+
21+
##################################################
22+
## ECS Service
23+
##################################################
24+
25+
resource "aws_ecs_service" "main_service" {
26+
name = "${var.project_name_prefix}-service"
27+
cluster = aws_ecs_cluster.main_cluster.id
28+
task_definition = aws_ecs_task_definition.app_task.arn
29+
desired_count = var.task_desired_count
30+
launch_type = "FARGATE"
31+
platform_version = "LATEST"
32+
33+
health_check_grace_period_seconds = 60
34+
35+
enable_ecs_managed_tags = true
36+
propagate_tags = "TASK_DEFINITION"
37+
38+
deployment_controller {
39+
type = "ECS"
40+
}
41+
deployment_minimum_healthy_percent = 100
42+
deployment_maximum_percent = 200
43+
44+
network_configuration {
45+
subnets = [
46+
aws_subnet.private[0].id,
47+
aws_subnet.private[1].id
48+
]
49+
security_groups = [aws_security_group.ecs_tasks_sg.id]
50+
assign_public_ip = false
51+
}
52+
53+
load_balancer {
54+
target_group_arn = aws_lb_target_group.app_tg.arn
55+
container_name = "node-hw"
56+
container_port = var.app_port
57+
}
58+
59+
depends_on = [aws_lb_listener.http_listener]
60+
61+
tags = merge(
62+
var.common_tags,
63+
{
64+
Name = "${var.project_name_prefix}-service"
65+
}
66+
)
67+
}

0 commit comments

Comments
 (0)