Skip to content

Commit

Permalink
Tech challenge - github actions
Browse files Browse the repository at this point in the history
  • Loading branch information
BalajiDeepthi committed Feb 25, 2025
1 parent 5024b64 commit 81498c5
Show file tree
Hide file tree
Showing 4 changed files with 347 additions and 0 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# .github/workflows/deploy.yml
name: Deploy Symfony App to ECS

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Build and push Docker image
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: BalajiDeepthi
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Deploy to Amazon ECS
id: deploy-ecs
uses: aws-actions/amazon-ecs-deploy@v1
with:
cluster: phpDemoECS
service: phpDemoApp
task-definition: task-definition.json
force-new-deployment: true
wait-for-service-stability: true
task-definition-template-json: task-definition.json
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Dockerfile
FROM php:8.1-apache

# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
zip \
unzip \
libzip-dev \
&& docker-php-ext-install zip pdo_mysql

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Set working directory
WORKDIR /var/www/html

# Copy application code
COPY . .

# Install PHP dependencies
RUN composer install --no-interaction --prefer-dist --optimize-autoloader

# Set permissions
RUN chown -R www-data:www-data /var/www/html/var && chmod -R 775 /var/www/html/var

# Expose port 80
EXPOSE 80

# Configure Apache (optional, if you need custom config)
# COPY apache2.conf /etc/apache2/sites-available/000-default.conf

# Start Apache
CMD ["apache2-foreground"]
4 changes: 4 additions & 0 deletions task-definition.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"family": "symfony-app",
"containerDefinitions": []
}
262 changes: 262 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
# main.tf
provider "aws" {
region = "us-east-1"
}

resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
}

resource "aws_instance" "app" {
ami = "ami-0c55b159cbfafe1f0" # Example Ubuntu AMI
instance_type = "t2.micro"
subnet_id = aws_subnet.public.id

user_data = <<-EOF
#!/bin/bash
# Install PHP, MySQL, Composer, etc.
sudo apt update
sudo apt install -y apache2 php libapache2-mod-php php-mysql mysql-client composer unzip git
# Copy and configure the Symfony application (done by the pipeline)
EOF

vpc_security_group_ids = [aws_security_group.app.id]
}

resource "aws_security_group" "app" {
vpc_id = aws_vpc.main.id

ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["192.168.2.15/32"] # Restrict SSH access
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

resource "aws_db_instance" "db" {
allocated_storage = 20
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t2.micro"
name = "symfony_db"
username = "admin"
password = "password123" # Securely manage passwords
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.db.id]
}

resource "aws_security_group" "db" {
vpc_id = aws_vpc.main.id

ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = [aws_security_group.app.id]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

resource "aws_ecs_cluster" "cluster" {
name = "phpDemoECS"
}

resource "aws_ecr_repository" "repository" {
name = "balajideepthi"
}

resource "aws_ecs_service" "service" {
name = "phpDemoApp"
cluster = aws_ecs_cluster.cluster.id
task_definition = aws_ecs_task_definition.task.arn
desired_count = 1
launch_type = "FARGATE"
network_configuration {
subnets = [aws_subnet.public.id]
security_groups = [aws_security_group.app.id]
}

load_balancer {
target_group_arn = aws_alb_target_group.arn
container_name = "symfony-app"
container_port = 80
}
}

resource "aws_ecs_task_definition" "task" {
family = "symfony-app"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = 256
memory = 512
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
container_definitions = jsonencode([
{
name = "symfony-app",
image = "${aws_ecr_repository.repository.repository_url}:${var.image_tag}",
portMappings = [
{
containerPort = 80,
hostPort = 80
}
],
environment = [
{
name = "DATABASE_URL",
value = "mysql://admin:${var.db_password}@${var.db_endpoint}:3306/symfony_db?serverVersion=8.0"
}
],
logConfiguration = {
logDriver = "awslogs",
options = {
"awslogs-group" : aws_cloudwatch_log_group.log_group.name,
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
])
}

resource "aws_security_group" "alb" {
name = "symfony-alb-sg"
description = "Security group for ALB"
vpc_id = aws_vpc.main.id

ingress {
description = "Allow HTTP traffic"
from_port = 80
to_port = 80
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"]
}
}


resource "aws_iam_role" "ecs_task_execution_role" {
name = "ecs-task-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Action = "sts:AssumeRole",
Effect = "Allow",
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
}
]
})
}

resource "aws_iam_policy" "ecs_task_execution_policy" {
name = "ecs-task-execution-policy"
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Action = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
Effect = "Allow",
Resource = "*"
}
]
})
}

resource "aws_iam_role_policy_attachment" "ecs_task_execution_policy_attachment" {
role = aws_iam_role.ecs_task_execution_role.name
policy_arn = aws_iam_policy.ecs_task_execution_policy.arn
}

resource "aws_cloudwatch_log_group" "log_group" {
name = "/ecs/symfony-app"
}

resource "aws_alb" "alb" {
name = "symfony-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = [aws_subnet.public.id]
tags = {
Environment = "production"
}
}

resource "aws_alb_target_group" "target_group" {
name = "symfony-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
target_type = "ip"

health_check {
path = "/health"
protocol = "HTTP"
matcher = "200"
}
}

resource "aws_alb_listener" "listener" {
load_balancer_arn = aws_alb.alb.arn
port = 80
protocol = "HTTP"

default_action {
target_group_arn = aws_alb_target_group.target_group.arn
type = "forward"
}
}

output "alb_dns_name" {
value = aws_alb.alb.dns_name
}

output "app_public_ip" {
value = aws_instance.app.public_ip
}

output "db_endpoint" {
value = aws_db_instance.db.endpoint
}

0 comments on commit 81498c5

Please sign in to comment.