Skip to content

Task 6: Application Deployment via Jenkins Pipeline #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4748b09
feat: add terraform config files
elian-cheng Sep 23, 2024
28ceaa6
fix: variables formatting
elian-cheng Sep 23, 2024
18908e3
fix: aws configs
elian-cheng Sep 23, 2024
96171d2
fix: workflow credentials access
elian-cheng Sep 23, 2024
962d857
fix: replace variables in main.tf
elian-cheng Sep 23, 2024
d194990
feat: add workflow secrets
elian-cheng Sep 23, 2024
032f988
fix: skip exising bucket and iam role creation
elian-cheng Sep 23, 2024
55449a5
fix: format check
elian-cheng Sep 23, 2024
497f4f5
fix: s3 bucket count
elian-cheng Sep 23, 2024
ecbb6a0
fix: attach role policies
elian-cheng Sep 30, 2024
3a5979d
fix: existing role check
elian-cheng Sep 30, 2024
4f4fe92
feat: add K8s cluster basic networking infrastructure
elian-cheng Oct 11, 2024
d6d9c73
fix: duplicate data error
elian-cheng Oct 11, 2024
f1f960f
fix: add cache clearing
elian-cheng Oct 11, 2024
f4a834b
fix: add public SSH key to GitHub secrets
elian-cheng Oct 11, 2024
c3d65a1
fix: terraform formatting
elian-cheng Oct 11, 2024
9693e90
feat: add K3s cluster configs
elian-cheng Oct 20, 2024
4970fc0
fix: key name
elian-cheng Oct 20, 2024
27c6e19
docs: update readme
elian-cheng Oct 20, 2024
f6fbe09
feat: add jenkins install and configs
elian-cheng Nov 3, 2024
0d70ba6
fix: remove bastion host reference
elian-cheng Nov 3, 2024
964213f
fix: initial script
elian-cheng Nov 3, 2024
7762347
fix: security group
elian-cheng Nov 3, 2024
7c8a33b
fix: volumes folder
elian-cheng Nov 3, 2024
c547124
fix: jenkins role management from helm
elian-cheng Nov 3, 2024
59e2d46
feat: change ec2 user data to deploy wordpress app
elian-cheng Nov 10, 2024
c94bcfd
fix: script issues
elian-cheng Nov 10, 2024
a6e78c3
fix: user-data script
elian-cheng Nov 10, 2024
61fe251
feat: add necessary changes for jenkins
elian-cheng Nov 23, 2024
3d6b1fe
feat: change sonar url place
elian-cheng Nov 23, 2024
a0630f6
feat: change instance type
elian-cheng Nov 23, 2024
2316ba8
fix: checking state for the sonarQube
elian-cheng Nov 23, 2024
b9f9b8a
fix: scripts
elian-cheng Nov 23, 2024
2f43060
feat: change sonar qube step
elian-cheng Nov 23, 2024
18c686d
feat: change scripts
elian-cheng Nov 23, 2024
57e34a8
docs: update Readme.md
elian-cheng Nov 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/terraform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Terraform Deployment

on:
pull_request:
branches:
- main
push:
branches:
- main

permissions:
id-token: write
contents: read

jobs:
terraform-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3

- name: Terraform Format Check
run: terraform fmt -check

terraform-plan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/GithubActionsRole
aws-region: ${{ secrets.AWS_REGION }}
audience: sts.amazonaws.com

- name: Clear Terraform cache
run: rm -rf .terraform

- name: Terraform Init
run: terraform init

- name: Terraform Plan
run: terraform plan -var="private_key=${{ secrets.AWS_EC2_PRIVATE_KEY }}"

terraform-apply:
runs-on: ubuntu-latest
needs: terraform-plan
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/GithubActionsRole
aws-region: ${{ secrets.AWS_REGION }}
audience: sts.amazonaws.com

- name: Clear Terraform cache
run: rm -rf .terraform

- name: Terraform Init
run: terraform init

- name: Terraform Apply
run: terraform apply -auto-approve -var="private_key=${{ secrets.AWS_EC2_PRIVATE_KEY }}"
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.env
.idea/
.terraform/
.terraform.lock.hcl
*.pem
k3s.yaml
goals-app/node_modules/
227 changes: 227 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
metadata:
labels:
some-label: some-label-value
spec:
containers:
- name: node
image: timbru31/node-alpine-git
command:
- cat
tty: true
- name: docker
image: docker:24.0.5
command:
- cat
tty: true
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
- name: sonarscanner
image: sonarsource/sonar-scanner-cli
command:
- cat
tty: true
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
'''
retries 2
}
}
parameters {
booleanParam(name: 'SHOULD_PUSH_TO_ECR', defaultValue: false, description: 'Set to true in build with params to push Docker image to ECR')
}
triggers {
GenericTrigger(
causeString: 'Triggered by GitHub Push',
token: 'my-git-token',
printPostContent: true,
printContributedVariables: true,
silentResponse: false
)
}
environment {
AWS_ACCOUNT_ID = '656732674839'
AWS_REGION = 'eu-north-1'
AWS_CREDENTIALS = 'aws-credentials'
REPO_NAME = 'goals-app'
IMAGE_TAG = 'latest'
SONAR_PROJECT_KEY = "Goals-App-Check"
SONAR_LOGIN = "sqp_1c229ea811bd6e48b5b08b84f17052332323ea86"
SONAR_HOST_URL = "http://51.20.106.145:9000"
}
stages {
stage('Prepare') {
steps {
container('node') {
script {
echo "Cloning repository..."
sh '''
git clone https://github.com/elian-cheng/rsschool-task6-docker-app app
cd app
echo "Repo files:"
ls -la
'''
}
}
}
}

stage('Install Dependencies') {
steps {
container('node') {
script {
echo "Installing dependencies..."
sh '''
cd app
npm install
'''
}
}
}
}

stage('Run Tests') {
steps {
container('node') {
script {
echo "Running tests..."
sh '''
cd app
npm test
'''
}
}
}
}

stage('SonarQube Analysis') {
steps {
container('sonarscanner') {
script {
echo "Running SonarQube analysis..."
sh '''
sonar-scanner \
-Dsonar.projectKey=${SONAR_PROJECT_KEY} \
-Dsonar.sources=. \
-Dsonar.host.url=${SONAR_HOST_URL} \
-Dsonar.login=${SONAR_LOGIN}
'''
}
}
}
}

stage('Install AWS CLI') {
steps {
container('docker') {
script {
echo "Installing AWS CLI..."
sh '''
apk add --no-cache python3 py3-pip
pip3 install awscli
aws --version
'''
}
}
}
}

stage('Build Docker Image') {
steps {
container('docker') {
script {
echo "Building Docker image..."
sh '''
cd app
pwd
docker build -t goals-app:latest -f Dockerfile .
'''
}
}
}
}

stage('Push Docker image to ECR') {
when { expression { params.SHOULD_PUSH_TO_ECR == true } }
steps {
container('docker') {
script {
echo "Pushing Docker image to ECR..."
withAWS(credentials: "${AWS_CREDENTIALS}", region: "${AWS_REGION}") {
sh '''
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPO_NAME}
docker tag ${REPO_NAME}:${IMAGE_TAG} ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPO_NAME}:${IMAGE_TAG}
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPO_NAME}:${IMAGE_TAG}
'''
}
}
}
}
}

stage('Create ECR Secret') {
steps {
container('docker') {
script {
echo "Creating ECR secret..."
withAWS(credentials: "${AWS_CREDENTIALS}", region: "${AWS_REGION}") {
sh '''
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPO_NAME}
kubectl create secret generic ecr-secret --namespace=jenkins --from-file=.dockerconfigjson=\$HOME/.docker/config.json --dry-run=client -o json | kubectl apply -f -
'''
}
}
}
}
}

stage('Deploy to Kubernetes with Helm') {
when { expression { params.SHOULD_PUSH_TO_ECR == true } }
steps {
container('helm') {
script {
echo "Deploying to Kubernetes with Helm..."
withAWS(credentials: "${AWS_CREDENTIALS}", region: "${AWS_REGION}") {
sh '''
helm upgrade --install ${REPO_NAME} ./helm/${REPO_NAME} \\
--set image.repository=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPO_NAME} \\
--set image.tag=${IMAGE_TAG} \\
-f ./helm/${REPO_NAME}/values.yaml \\
--namespace default '''
}
}
}
}
}
}
post {
success {
script {
echo "Pipeline completed successfully!"
emailext(
subject: 'Jenkins Pipeline Success',
body: "Pipeline '${env.JOB_NAME}' (#${env.BUILD_NUMBER}) completed successfully.\n\nCheck results: ${env.BUILD_URL}",
to: 'eliang.cheng@gmail.com'
)
}
}
failure {
script {
echo "Pipeline failed!"
emailext(
subject: 'Jenkins Pipeline Failure',
body: "Pipeline '${env.JOB_NAME}' (#${env.BUILD_NUMBER}) failed.\n\nCheck the details here: ${env.BUILD_URL}",
to: 'eliang.cheng@gmail.com'
)
}
}
}
}
Loading