diff --git a/Jenkins(ci-cd)/Jenkinsfile b/Jenkins(ci-cd)/Jenkinsfile new file mode 100644 index 0000000..e569bf5 --- /dev/null +++ b/Jenkins(ci-cd)/Jenkinsfile @@ -0,0 +1,77 @@ +pipeline { + agent any + + environment { + REPO_URL = "https://github.com/ankitsubhamjyoti2005/DevOps-Assessment" + IMAGE_NAME = "your-ecr-repo-url/nx-app:latest" + AWS_REGION = "us-west-2" + DOCKER_CREDENTIALS_ID = "docker-hub-credentials" + TERRAFORM_CREDENTIALS_ID = "aws-credentials" + } + + stages { + stage('Checkout Code') { + steps { + git branch: 'main', url: "${env.REPO_URL}" + } + } + + stage('Build Docker Image') { + steps { + script { + docker.build("${env.IMAGE_NAME}") + } + } + } + + stage('Push Docker Image to ECR') { + steps { + withCredentials([usernamePassword(credentialsId: "${env.DOCKER_CREDENTIALS_ID}", passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USERNAME')]) { + sh """ + echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin + docker push ${env.IMAGE_NAME} + """ + } + } + } + + stage('Terraform Init') { + steps { + withCredentials([usernamePassword(credentialsId: "${env.TERRAFORM_CREDENTIALS_ID}", passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { + dir('terraform') { + sh 'terraform init' + } + } + } + } + + stage('Terraform Apply') { + steps { + withCredentials([usernamePassword(credentialsId: "${env.TERRAFORM_CREDENTIALS_ID}", passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { + dir('terraform') { + sh 'terraform apply -auto-approve -var="docker_image=${env.IMAGE_NAME}"' + } + } + } + } + + stage('Deploy to AWS Fargate') { + steps { + script { + echo "Deploying the application using ECS Fargate..." + dir('terraform') { + withCredentials([usernamePassword(credentialsId: "${env.TERRAFORM_CREDENTIALS_ID}", passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { + sh 'terraform apply -auto-approve' + } + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} diff --git a/Jenkins(ci-cd)/requirments b/Jenkins(ci-cd)/requirments new file mode 100644 index 0000000..2a04e5f --- /dev/null +++ b/Jenkins(ci-cd)/requirments @@ -0,0 +1,11 @@ +Jenkins Server: You need a running Jenkins instance + + +Jenkins Plugins: + -Docker Pipeline Plugin + -Terraform Plugin + -Git Plugin + +Jenkins Credentials: + -Docker Registry credentials (e.g., Docker Hub or AWS ECR). + -AWS credentials (Access Key ID and Secret Access Key) for Terraform. \ No newline at end of file diff --git a/terraform/Dockerfile b/terraform/Dockerfile new file mode 100644 index 0000000..7612479 --- /dev/null +++ b/terraform/Dockerfile @@ -0,0 +1,25 @@ +FROM node:18-alpine AS build + +WORKDIR /app + +COPY package*.json ./ + +RUN npm install + +COPY . . + +RUN npx nx build pt-notification-service --configuration=production + +FROM node:18-alpine + +WORKDIR /app + +COPY --from=build /app/dist/apps/pt-notification-service ./pt-notification-service + +# Install production dependencies +COPY package*.json ./ +RUN npm install --only=production + +# Expose the port +EXPOSE 3000 +CMD ["node", "pt-notification-service/main.js"] \ No newline at end of file diff --git a/terraform/autoscaling.tf b/terraform/autoscaling.tf deleted file mode 100644 index e69de29..0000000 diff --git a/terraform/cluster.tf b/terraform/cluster.tf deleted file mode 100644 index e69de29..0000000 diff --git a/terraform/ecr.tf b/terraform/ecr.tf deleted file mode 100644 index e69de29..0000000 diff --git a/terraform/ecs-cluster.tf b/terraform/ecs-cluster.tf new file mode 100644 index 0000000..0aeae36 --- /dev/null +++ b/terraform/ecs-cluster.tf @@ -0,0 +1,25 @@ +resource "aws_ecs_task_definition" "nx_task" { + family = "nx-task" + network_mode = "awsvpc" + requires_compatibilities = ["FARGATE"] + cpu = "4096" + memory = "8192" + + execution_role_arn = aws_iam_role.ecs_task_execution_role.arn + task_role_arn = aws_iam_role.ecs_task_execution_role.arn + + container_definitions = jsonencode([ + { + name = "nx-app-container" + image = "your-docker-image:latest" + portMappings = [ + { + containerPort = 3000 + hostPort = 3000 + protocol = "tcp" + } + ] + essential = true + } + ]) +} diff --git a/terraform/ecs-service.tf b/terraform/ecs-service.tf new file mode 100644 index 0000000..8b37f50 --- /dev/null +++ b/terraform/ecs-service.tf @@ -0,0 +1,19 @@ +resource "aws_ecs_service" "nx_service" { + name = "nx-app-service" + cluster = aws_ecs_cluster.main.id + task_definition = aws_ecs_task_definition.nx_task.arn + desired_count = 1 + launch_type = "FARGATE" + + network_configuration { + subnets = aws_subnet.main[*].id + security_groups = [aws_security_group.web_sg.id] + assign_public_ip = true + } + + load_balancer { + target_group_arn = aws_lb_target_group.main.arn + container_name = "nx-app-container" + container_port = 3000 + } +} diff --git a/terraform/iam-roles.tf b/terraform/iam-roles.tf new file mode 100644 index 0000000..3bfafbb --- /dev/null +++ b/terraform/iam-roles.tf @@ -0,0 +1,20 @@ +resource "aws_iam_role" "ecs_task_execution_role" { + name = "ecsTaskExecutionRole" + + assume_role_policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Action = "sts:AssumeRole", + Effect = "Allow", + Principal = { + Service = "ecs-tasks.amazonaws.com" + } + } + ] + }) + + managed_policy_arns = [ + "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" + ] +} diff --git a/terraform/load-balancer.tf b/terraform/load-balancer.tf new file mode 100644 index 0000000..d4d968f --- /dev/null +++ b/terraform/load-balancer.tf @@ -0,0 +1,25 @@ +resource "aws_lb" "main" { + name = "nx-app-lb" + internal = false + load_balancer_type = "application" + security_groups = [aws_security_group.web_sg.id] + subnets = aws_subnet.main[*].id +} + +resource "aws_lb_target_group" "main" { + name = "nx-app-tg" + port = 3000 + protocol = "HTTP" + vpc_id = aws_vpc.main.id +} + +resource "aws_lb_listener" "main" { + load_balancer_arn = aws_lb.main.arn + port = 3000 + protocol = "HTTP" + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.main.arn + } +} diff --git a/terraform/main.tf b/terraform/main.tf deleted file mode 100644 index e69de29..0000000 diff --git a/terraform/network.tf b/terraform/network.tf new file mode 100644 index 0000000..d3c451a --- /dev/null +++ b/terraform/network.tf @@ -0,0 +1,25 @@ +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_subnet" "main" { + count = 2 + vpc_id = aws_vpc.main.id + cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 4, count.index) +} + +resource "aws_security_group" "web_sg" { + vpc_id = aws_vpc.main.id + ingress { + from_port = 3000 + to_port = 3000 + 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"] + } +} diff --git a/terraform/provider.tf b/terraform/provider.tf index e69de29..c28c97a 100644 --- a/terraform/provider.tf +++ b/terraform/provider.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "us-west-2" +} diff --git a/terraform/secrets-manager.tf b/terraform/secrets-manager.tf deleted file mode 100644 index e69de29..0000000 diff --git a/terraform/service.tf b/terraform/service.tf deleted file mode 100644 index e69de29..0000000