1+ resource "aws_security_group" "lb_sg" {
2+ name = " demo-lb-sg"
3+ description = " Allow HTTP inbound traffic"
4+ vpc_id = aws_vpc. main . id
5+
6+ ingress {
7+ from_port = 80
8+ to_port = 80
9+ protocol = " tcp"
10+ cidr_blocks = [" 0.0.0.0/0" ]
11+ }
12+
13+ egress {
14+ from_port = 0
15+ to_port = 0
16+ protocol = " -1"
17+ cidr_blocks = [" 0.0.0.0/0" ]
18+ }
19+ }
20+
21+ resource "aws_security_group" "ecs_sg" {
22+ name = " demo-ecs-tasks-sg"
23+ description = " Allow inbound traffic from the LB"
24+ vpc_id = aws_vpc. main . id
25+
26+ ingress {
27+ from_port = 8080
28+ to_port = 8080
29+ protocol = " tcp"
30+ security_groups = [aws_security_group . lb_sg . id ]
31+ }
32+
33+ egress {
34+ from_port = 0
35+ to_port = 0
36+ protocol = " -1"
37+ cidr_blocks = [" 0.0.0.0/0" ]
38+ }
39+ }
40+
41+ # ECR
42+ resource "aws_ecr_repository" "app_repo" {
43+ name = " demo-assignment-repo"
44+ image_tag_mutability = " MUTABLE"
45+ }
46+
47+ # ALB
48+ resource "aws_lb" "main" {
49+ name = " demo-app-lb"
50+ internal = false
51+ load_balancer_type = " application"
52+ security_groups = [aws_security_group . lb_sg . id ]
53+ subnets = [aws_subnet . public_a . id , aws_subnet . public_b . id ]
54+ }
55+
56+ # Target Group for ALB
57+ resource "aws_lb_target_group" "main" {
58+ name = " demo-app-tg"
59+ port = 8080
60+ protocol = " HTTP"
61+ vpc_id = aws_vpc. main . id
62+ target_type = " ip"
63+
64+ health_check {
65+ path = " /" # Flask app's login page is at the root
66+ }
67+ }
68+
69+ # Listener for ALB on port 80
70+ resource "aws_lb_listener" "http" {
71+ load_balancer_arn = aws_lb. main . arn
72+ port = 80
73+ protocol = " HTTP"
74+
75+ default_action {
76+ type = " forward"
77+ target_group_arn = aws_lb_target_group. main . arn
78+ }
79+ }
80+
81+ # ECS Cluster
82+ resource "aws_ecs_cluster" "main" {
83+ name = " demo-cluster"
84+ }
85+
86+ resource "aws_iam_role" "ecs_task_execution_role" {
87+ name = " demo-ecs-task-execution-role"
88+ assume_role_policy = jsonencode ({
89+ Version = " 2012-10-17"
90+ Statement = [{
91+ Action = " sts:AssumeRole"
92+ Effect = " Allow"
93+ Principal = {
94+ Service = " ecs-tasks.amazonaws.com"
95+ }
96+ }]
97+ })
98+ }
99+
100+
101+ resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" {
102+ role = aws_iam_role. ecs_task_execution_role . name
103+ policy_arn = " arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
104+ }
105+
106+ # CloudWatch Log Group
107+ resource "aws_cloudwatch_log_group" "app_logs" {
108+ name = " /ecs/demo-app"
109+ }
110+
111+ # ECS Task Definition
112+ resource "aws_ecs_task_definition" "app_task" {
113+ family = " demo-app-task"
114+ network_mode = " awsvpc"
115+ requires_compatibilities = [" FARGATE" ]
116+ cpu = 256
117+ memory = 512
118+ execution_role_arn = aws_iam_role. ecs_task_execution_role . arn
119+
120+ container_definitions = jsonencode ([
121+ {
122+ name = " demo-app-container"
123+ image = var.docker_image_url
124+ essential = true
125+ portMappings = [
126+ {
127+ containerPort = 8080
128+ hostPort = 8080
129+ }
130+ ]
131+ logConfiguration = {
132+ logDriver = " awslogs"
133+ options = {
134+ " awslogs-group" = aws_cloudwatch_log_group.app_logs.name
135+ " awslogs-region" = " ap-south-1"
136+ " awslogs-stream-prefix" = " ecs"
137+ }
138+ }
139+ }
140+ ])
141+ }
142+
143+ # ECS Service
144+ resource "aws_ecs_service" "main" {
145+ name = " demo-app-service"
146+ cluster = aws_ecs_cluster. main . id
147+ task_definition = aws_ecs_task_definition. app_task . arn
148+ desired_count = 1
149+ launch_type = " FARGATE"
150+
151+ network_configuration {
152+ subnets = [aws_subnet . public_a . id , aws_subnet . public_b . id ]
153+ security_groups = [aws_security_group . ecs_sg . id ]
154+ assign_public_ip = true
155+ }
156+
157+ load_balancer {
158+ target_group_arn = aws_lb_target_group. main . arn
159+ container_name = " demo-app-container"
160+ container_port = 8080
161+ }
162+
163+ depends_on = [aws_lb_listener . http ]
164+ }
165+
166+ output "app_url" {
167+ value = aws_lb. main . dns_name
168+ }
0 commit comments