Skip to content

Commit 81498c5

Browse files
committed
Tech challenge - github actions
1 parent 5024b64 commit 81498c5

File tree

4 files changed

+347
-0
lines changed

4 files changed

+347
-0
lines changed

.github/workflows/deploy.yml

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# .github/workflows/deploy.yml
2+
name: Deploy Symfony App to ECS
3+
4+
on:
5+
push:
6+
branches:
7+
- main
8+
9+
jobs:
10+
deploy:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v3
16+
17+
- name: Configure AWS credentials
18+
uses: aws-actions/configure-aws-credentials@v1
19+
with:
20+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
21+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
22+
aws-region: ${{ secrets.AWS_REGION }}
23+
24+
- name: Login to Amazon ECR
25+
id: login-ecr
26+
uses: aws-actions/amazon-ecr-login@v1
27+
28+
- name: Build and push Docker image
29+
id: build-image
30+
env:
31+
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
32+
ECR_REPOSITORY: BalajiDeepthi
33+
IMAGE_TAG: ${{ github.sha }}
34+
run: |
35+
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
36+
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
37+
38+
- name: Deploy to Amazon ECS
39+
id: deploy-ecs
40+
uses: aws-actions/amazon-ecs-deploy@v1
41+
with:
42+
cluster: phpDemoECS
43+
service: phpDemoApp
44+
task-definition: task-definition.json
45+
force-new-deployment: true
46+
wait-for-service-stability: true
47+
task-definition-template-json: task-definition.json

Dockerfile

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Dockerfile
2+
FROM php:8.1-apache
3+
4+
# Install system dependencies
5+
RUN apt-get update && apt-get install -y \
6+
git \
7+
zip \
8+
unzip \
9+
libzip-dev \
10+
&& docker-php-ext-install zip pdo_mysql
11+
12+
# Install Composer
13+
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
14+
15+
# Set working directory
16+
WORKDIR /var/www/html
17+
18+
# Copy application code
19+
COPY . .
20+
21+
# Install PHP dependencies
22+
RUN composer install --no-interaction --prefer-dist --optimize-autoloader
23+
24+
# Set permissions
25+
RUN chown -R www-data:www-data /var/www/html/var && chmod -R 775 /var/www/html/var
26+
27+
# Expose port 80
28+
EXPOSE 80
29+
30+
# Configure Apache (optional, if you need custom config)
31+
# COPY apache2.conf /etc/apache2/sites-available/000-default.conf
32+
33+
# Start Apache
34+
CMD ["apache2-foreground"]

task-definition.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"family": "symfony-app",
3+
"containerDefinitions": []
4+
}

terraform/main.tf

+262
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
# main.tf
2+
provider "aws" {
3+
region = "us-east-1"
4+
}
5+
6+
resource "aws_vpc" "main" {
7+
cidr_block = "10.0.0.0/16"
8+
}
9+
10+
resource "aws_subnet" "public" {
11+
vpc_id = aws_vpc.main.id
12+
cidr_block = "10.0.1.0/24"
13+
availability_zone = "us-east-1a"
14+
}
15+
16+
resource "aws_instance" "app" {
17+
ami = "ami-0c55b159cbfafe1f0" # Example Ubuntu AMI
18+
instance_type = "t2.micro"
19+
subnet_id = aws_subnet.public.id
20+
21+
user_data = <<-EOF
22+
#!/bin/bash
23+
# Install PHP, MySQL, Composer, etc.
24+
sudo apt update
25+
sudo apt install -y apache2 php libapache2-mod-php php-mysql mysql-client composer unzip git
26+
# Copy and configure the Symfony application (done by the pipeline)
27+
EOF
28+
29+
vpc_security_group_ids = [aws_security_group.app.id]
30+
}
31+
32+
resource "aws_security_group" "app" {
33+
vpc_id = aws_vpc.main.id
34+
35+
ingress {
36+
from_port = 80
37+
to_port = 80
38+
protocol = "tcp"
39+
cidr_blocks = ["0.0.0.0/0"]
40+
}
41+
42+
ingress {
43+
from_port = 22
44+
to_port = 22
45+
protocol = "tcp"
46+
cidr_blocks = ["192.168.2.15/32"] # Restrict SSH access
47+
}
48+
49+
egress {
50+
from_port = 0
51+
to_port = 0
52+
protocol = "-1"
53+
cidr_blocks = ["0.0.0.0/0"]
54+
}
55+
}
56+
57+
resource "aws_db_instance" "db" {
58+
allocated_storage = 20
59+
engine = "mysql"
60+
engine_version = "8.0"
61+
instance_class = "db.t2.micro"
62+
name = "symfony_db"
63+
username = "admin"
64+
password = "password123" # Securely manage passwords
65+
skip_final_snapshot = true
66+
vpc_security_group_ids = [aws_security_group.db.id]
67+
}
68+
69+
resource "aws_security_group" "db" {
70+
vpc_id = aws_vpc.main.id
71+
72+
ingress {
73+
from_port = 3306
74+
to_port = 3306
75+
protocol = "tcp"
76+
security_groups = [aws_security_group.app.id]
77+
}
78+
79+
egress {
80+
from_port = 0
81+
to_port = 0
82+
protocol = "-1"
83+
cidr_blocks = ["0.0.0.0/0"]
84+
}
85+
}
86+
87+
resource "aws_ecs_cluster" "cluster" {
88+
name = "phpDemoECS"
89+
}
90+
91+
resource "aws_ecr_repository" "repository" {
92+
name = "balajideepthi"
93+
}
94+
95+
resource "aws_ecs_service" "service" {
96+
name = "phpDemoApp"
97+
cluster = aws_ecs_cluster.cluster.id
98+
task_definition = aws_ecs_task_definition.task.arn
99+
desired_count = 1
100+
launch_type = "FARGATE"
101+
network_configuration {
102+
subnets = [aws_subnet.public.id]
103+
security_groups = [aws_security_group.app.id]
104+
}
105+
106+
load_balancer {
107+
target_group_arn = aws_alb_target_group.arn
108+
container_name = "symfony-app"
109+
container_port = 80
110+
}
111+
}
112+
113+
resource "aws_ecs_task_definition" "task" {
114+
family = "symfony-app"
115+
network_mode = "awsvpc"
116+
requires_compatibilities = ["FARGATE"]
117+
cpu = 256
118+
memory = 512
119+
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
120+
container_definitions = jsonencode([
121+
{
122+
name = "symfony-app",
123+
image = "${aws_ecr_repository.repository.repository_url}:${var.image_tag}",
124+
portMappings = [
125+
{
126+
containerPort = 80,
127+
hostPort = 80
128+
}
129+
],
130+
environment = [
131+
{
132+
name = "DATABASE_URL",
133+
value = "mysql://admin:${var.db_password}@${var.db_endpoint}:3306/symfony_db?serverVersion=8.0"
134+
}
135+
],
136+
logConfiguration = {
137+
logDriver = "awslogs",
138+
options = {
139+
"awslogs-group" : aws_cloudwatch_log_group.log_group.name,
140+
"awslogs-region": "us-east-1",
141+
"awslogs-stream-prefix": "ecs"
142+
}
143+
}
144+
}
145+
])
146+
}
147+
148+
resource "aws_security_group" "alb" {
149+
name = "symfony-alb-sg"
150+
description = "Security group for ALB"
151+
vpc_id = aws_vpc.main.id
152+
153+
ingress {
154+
description = "Allow HTTP traffic"
155+
from_port = 80
156+
to_port = 80
157+
protocol = "tcp"
158+
cidr_blocks = ["0.0.0.0/0"]
159+
}
160+
161+
egress {
162+
from_port = 0
163+
to_port = 0
164+
protocol = "-1"
165+
cidr_blocks = ["0.0.0.0/0"]
166+
}
167+
}
168+
169+
170+
resource "aws_iam_role" "ecs_task_execution_role" {
171+
name = "ecs-task-execution-role"
172+
assume_role_policy = jsonencode({
173+
Version = "2012-10-17",
174+
Statement = [
175+
{
176+
Action = "sts:AssumeRole",
177+
Effect = "Allow",
178+
Principal = {
179+
Service = "ecs-tasks.amazonaws.com"
180+
}
181+
}
182+
]
183+
})
184+
}
185+
186+
resource "aws_iam_policy" "ecs_task_execution_policy" {
187+
name = "ecs-task-execution-policy"
188+
policy = jsonencode({
189+
Version = "2012-10-17",
190+
Statement = [
191+
{
192+
Action = [
193+
"ecr:GetAuthorizationToken",
194+
"ecr:BatchCheckLayerAvailability",
195+
"ecr:GetDownloadUrlForLayer",
196+
"ecr:BatchGetImage",
197+
"logs:CreateLogStream",
198+
"logs:PutLogEvents"
199+
],
200+
Effect = "Allow",
201+
Resource = "*"
202+
}
203+
]
204+
})
205+
}
206+
207+
resource "aws_iam_role_policy_attachment" "ecs_task_execution_policy_attachment" {
208+
role = aws_iam_role.ecs_task_execution_role.name
209+
policy_arn = aws_iam_policy.ecs_task_execution_policy.arn
210+
}
211+
212+
resource "aws_cloudwatch_log_group" "log_group" {
213+
name = "/ecs/symfony-app"
214+
}
215+
216+
resource "aws_alb" "alb" {
217+
name = "symfony-alb"
218+
internal = false
219+
load_balancer_type = "application"
220+
security_groups = [aws_security_group.alb.id]
221+
subnets = [aws_subnet.public.id]
222+
tags = {
223+
Environment = "production"
224+
}
225+
}
226+
227+
resource "aws_alb_target_group" "target_group" {
228+
name = "symfony-target-group"
229+
port = 80
230+
protocol = "HTTP"
231+
vpc_id = aws_vpc.main.id
232+
target_type = "ip"
233+
234+
health_check {
235+
path = "/health"
236+
protocol = "HTTP"
237+
matcher = "200"
238+
}
239+
}
240+
241+
resource "aws_alb_listener" "listener" {
242+
load_balancer_arn = aws_alb.alb.arn
243+
port = 80
244+
protocol = "HTTP"
245+
246+
default_action {
247+
target_group_arn = aws_alb_target_group.target_group.arn
248+
type = "forward"
249+
}
250+
}
251+
252+
output "alb_dns_name" {
253+
value = aws_alb.alb.dns_name
254+
}
255+
256+
output "app_public_ip" {
257+
value = aws_instance.app.public_ip
258+
}
259+
260+
output "db_endpoint" {
261+
value = aws_db_instance.db.endpoint
262+
}

0 commit comments

Comments
 (0)