Skip to content

Merge pull request #61 from swamymudiga/feature/Assignment09 #1

Merge pull request #61 from swamymudiga/feature/Assignment09

Merge pull request #61 from swamymudiga/feature/Assignment09 #1

name: Build Packer Image
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
# POSTGRES_URL: ${{ secrets.DB_URL }}
POSTGRES_USER: ${{ secrets.DB_USERNAME }} # Username from GitHub Secrets
POSTGRES_PASSWORD: ${{ secrets.DB_PASSWORD }} # Password from GitHub Secrets
POSTGRES_DB: ${{ secrets.DB_NAME }} # Database name from GitHub Secrets
ports:
- 5432:5432
options: >-
--health-cmd="pg_isready -U DB_USERNAME"
--health-interval=10s
--health-timeout=5s
--health-retries=5
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout code
uses: actions/checkout@v3
# Installing Java JDK 17
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: 17
distribution: "temurin"
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582
- name: UserRestControllerTest Testing
env:
DB_URL: ${{ secrets.DB_URL }} # Database name from GitHub Secrets
DB_USERNAME: ${{ secrets.DB_USERNAME }} # Username from GitHub Secrets
DB_PASSWORD: ${{ secrets.DB_PASSWORD }} # Password from GitHub Secrets
BANNER: ${{secrets.BANNER}}
APPLICATION_NAME: ${{secrets.APPLICATION_NAME}}
SHOW_SQL: ${{secrets.SHOW_SQL}}
NON_CONTEXTUAL_CREATION: ${{secrets.NON_CONTEXTUAL_CREATION}}
HIBERNATE_DIALECT_POSTGRESDIALECT: ${{secrets.HIBERNATE_DIALECT_POSTGRESDIALECT}}
HIBERNATE_DDL_AUTO: ${{secrets.HIBERNATE_DDL_AUTO}}
run: ./gradlew test
- name: Configure DEV AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
# Build Spring boot project and remove old artifacts
- name: Build project
run: ./gradlew bootJar
#Copy Jar file from local to workspace (ROOT.jar)
- name: Rename and Move Jar File
run: mv build/libs/webapp-0.0.1-SNAPSHOT.jar ROOT.jar
# Setup Packer
- name: Setup Packer
uses: hashicorp/setup-packer@main
# Initialise Packer
- name: Packer init
run: packer init ./webapp-main.pkr.hcl
# Format packer files
- name: Packer format
run: packer fmt -check ./webapp-main.pkr.hcl
# Validate Packer Files
- name: Packer validate
run: packer validate ./webapp-main.pkr.hcl
- name: Packer Build
run: |
packer build \
-var "aws_region=${{ secrets.AWS_REGION }}" \
-var "vpc_id=${{ secrets.VPC_ID }}" \
-var "source_ami=${{ secrets.SOURCE_AMI }}" \
-var "ssh_username=ubuntu" \
-var "subnet_id=${{ secrets.SUBNET_ID }}" \
-var "jar_file=ROOT.jar" \
./webapp-main.pkr.hcl
- name: Retrieve Latest AMI ID
id: get-ami-id
run: |
AMI_ID=$(aws ec2 describe-images \
--owners self \
--filters 'Name=name,Values=Swamy_Webapp-*' \
--query 'Images | sort_by(@, &CreationDate)[-1].ImageId' \
--output text)
if [ "$AMI_ID" == "None" ]; then
echo "Error: No AMI found matching the name pattern."
exit 1
fi
echo "AMI_ID=$AMI_ID"
echo "AMI_ID=$AMI_ID" >> $GITHUB_ENV
- name: Share AMI with DEMO Account
run: |
aws ec2 modify-image-attribute --image-id ${{ env.AMI_ID }} --launch-permission "{\"Add\":[{\"UserId\":\"${{ secrets.DEMO_ACCOUNT_ID }}\"}]}"
# Fetching Environment Variables
- name: Fetch Environment Variables
id: fetch-env-vars
run: |
echo "IS_DEV_ENVIRONMENT=${{ vars.isDevEnvironment }}" >> $GITHUB_ENV
echo "IS_DEMO_ENVIRONMENT=${{ vars.isDemoEnvironment }}" >> $GITHUB_ENV
- name: Determine Environments to Run
id: determine-env
run: |
if [ "${{ env.IS_DEV_ENVIRONMENT }}" == "true" ] && [ "${{ env.IS_DEMO_ENVIRONMENT }}" == "true" ]; then
echo "ENVIRONMENTS=dev,demo" >> $GITHUB_ENV
elif [ "${{ env.IS_DEV_ENVIRONMENT }}" == "true" ]; then
echo "ENVIRONMENTS=dev" >> $GITHUB_ENV
elif [ "${{ env.IS_DEMO_ENVIRONMENT }}" == "true" ]; then
echo "ENVIRONMENTS=demo" >> $GITHUB_ENV
else
echo "Error: No environment selected!"
exit 1
fi
- name: Configure DEV AWS credentials
if: contains(env.ENVIRONMENTS, 'dev') # Ensures it runs only in the dev environment
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Process Dev Environment
if: contains(env.ENVIRONMENTS, 'dev')
run: |
echo "Running in Development Environment..."
# Add Dev-specific commands here
#aws ec2 modify-image-attribute --image-id ${{ env.AMI_ID }} --launch-permission "{\"Add\":[{\"UserId\":\"${{ secrets.DEV_ACCOUNT_ID }}\"]}"
echo "Update Launch Template started..."
#Update Launch Template
aws ec2 create-launch-template-version \
--launch-template-name "${{ secrets.LAUNCH_TEMPLATE_NAME }}" \
--source-version "\$Latest" \
--version-description "Updated with latest AMI ID" \
--launch-template-data "{\"ImageId\": \"${{ env.AMI_ID }}\"}"
echo "Update Launch Template created successfully..."
echo "Modify Launch Template started..."
aws ec2 modify-launch-template \
--launch-template-name "${{ secrets.LAUNCH_TEMPLATE_NAME }}" \
--default-version "\$Latest"
echo "Modify Launch Template modified successfully..."
#Start Instance Refresh
echo "Initializing REFRESH_ID..."
REFRESH_ID=$(aws autoscaling start-instance-refresh \
--auto-scaling-group-name "${{ secrets.AUTOSCALING_GROUP_NAME }}" \
--preferences '{"MinHealthyPercentage": 50}' \
--query 'InstanceRefreshId' \
--output text)
echo "REFRESH_ID=$REFRESH_ID" >> $GITHUB_ENV
echo "REFRESH_ID got initialized: $REFRESH_ID..."
# Wait for Instance Refresh to complete
echo "Waiting for Instance Refresh to complete..."
MAX_WAIT=1800 # 30 minutes timeout
echo "MAX_WAIT: $MAX_WAIT"
WAIT_INTERVAL=30 # Check every 30 seconds
echo "WAIT_INTERVAL: $WAIT_INTERVAL"
ELAPSED_TIME=0
echo "ELAPSED_TIME: $ELAPSED_TIME"
STATUS=$(aws autoscaling describe-instance-refreshes \
--auto-scaling-group-name "${{ secrets.AUTOSCALING_GROUP_NAME }}" \
--query "InstanceRefreshes[?InstanceRefreshId=='${REFRESH_ID}'].Status | [0]" \
--output text)
echo "STATUS: $STATUS"
while [ "$STATUS" == "InProgress" ] || [ "$STATUS" == "Pending" ] && [ $ELAPSED_TIME -lt $MAX_WAIT ]; do
echo "Inside While Loop Checking Instance Refresh status..."
STATUS=$(aws autoscaling describe-instance-refreshes \
--auto-scaling-group-name "${{ secrets.AUTOSCALING_GROUP_NAME }}" \
--query "InstanceRefreshes[?InstanceRefreshId=='${REFRESH_ID}'].Status | [0]" \
--output text)
echo "Current status: $STATUS"
if [ "$STATUS" == "Successful" ]; then
echo "Instance Refresh completed successfully."
break
elif [ "$STATUS" == "Failed" ] || [ "$STATUS" == "Cancelled" ]; then
REASON=$(aws autoscaling describe-instance-refreshes \
--auto-scaling-group-name "${{ secrets.AUTOSCALING_GROUP_NAME }}" \
--query "InstanceRefreshes[?InstanceRefreshId=='${REFRESH_ID}'].StatusReason | [0]" \
--output text)
echo "Error: Instance Refresh failed with status: $STATUS. Reason: $REASON"
exit 1
elif [ "$STATUS" == "Pending" ]; then
echo "Instance Refresh still in Pending status... continuing to wait."
else
echo "Instance Refresh still in progress..."
fi
sleep $WAIT_INTERVAL
ELAPSED_TIME=$((ELAPSED_TIME + WAIT_INTERVAL))
done
if [ $ELAPSED_TIME -ge $MAX_WAIT ]; then
echo "Error: Instance Refresh timed out after $MAX_WAIT seconds."
exit 1
fi
- name: Configure Demo AWS credentials
if: contains(env.ENVIRONMENTS, 'demo') # Ensures it runs only in the dev environment
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.DEMO_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEMO_AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Process Demo Environment
if: contains(env.ENVIRONMENTS, 'demo')
run: |
echo "Running in Demo Environment..."
# Add Demo-specific commands here
#aws ec2 modify-image-attribute --image-id ${{ env.AMI_ID }} --launch-permission "{\"Add\":[{\"UserId\":\"${{ secrets.DEMO_ACCOUNT_ID }}\"]}"
echo "Update Launch Template started..."
#Update Launch Template
aws ec2 create-launch-template-version \
--launch-template-name "${{ secrets.LAUNCH_TEMPLATE_NAME }}" \
--source-version "\$Latest" \
--version-description "Updated with latest AMI ID" \
--launch-template-data "{\"ImageId\": \"${{ env.AMI_ID }}\"}"
echo "Update Launch Template created successfully..."
echo "Modify Launch Template started..."
aws ec2 modify-launch-template \
--launch-template-name "${{ secrets.LAUNCH_TEMPLATE_NAME }}" \
--default-version "\$Latest"
echo "Modify Launch Template modified successfully..."
#Start Instance Refresh
echo "Initializing REFRESH_ID..."
REFRESH_ID=$(aws autoscaling start-instance-refresh \
--auto-scaling-group-name "${{ secrets.AUTOSCALING_GROUP_NAME }}" \
--preferences '{"MinHealthyPercentage": 50}' \
--query 'InstanceRefreshId' \
--output text)
echo "REFRESH_ID=$REFRESH_ID" >> $GITHUB_ENV
echo "REFRESH_ID got initialized: $REFRESH_ID..."
# Wait for Instance Refresh to complete
echo "Waiting for Instance Refresh to complete..."
MAX_WAIT=1800 # 30 minutes timeout
echo "MAX_WAIT: $MAX_WAIT"
WAIT_INTERVAL=30 # Check every 30 seconds
echo "WAIT_INTERVAL: $WAIT_INTERVAL"
ELAPSED_TIME=0
echo "ELAPSED_TIME: $ELAPSED_TIME"
STATUS=$(aws autoscaling describe-instance-refreshes \
--auto-scaling-group-name "${{ secrets.AUTOSCALING_GROUP_NAME }}" \
--query "InstanceRefreshes[?InstanceRefreshId=='${REFRESH_ID}'].Status | [0]" \
--output text)
echo "STATUS: $STATUS"
while [ "$STATUS" == "InProgress" ] || [ "$STATUS" == "Pending" ] && [ $ELAPSED_TIME -lt $MAX_WAIT ]; do
echo "Inside While Loop Checking Instance Refresh status..."
STATUS=$(aws autoscaling describe-instance-refreshes \
--auto-scaling-group-name "${{ secrets.AUTOSCALING_GROUP_NAME }}" \
--query "InstanceRefreshes[?InstanceRefreshId=='${REFRESH_ID}'].Status | [0]" \
--output text)
echo "Current status: $STATUS"
if [ "$STATUS" == "Successful" ]; then
echo "Instance Refresh completed successfully."
break
elif [ "$STATUS" == "Failed" ] || [ "$STATUS" == "Cancelled" ]; then
REASON=$(aws autoscaling describe-instance-refreshes \
--auto-scaling-group-name "${{ secrets.AUTOSCALING_GROUP_NAME }}" \
--query "InstanceRefreshes[?InstanceRefreshId=='${REFRESH_ID}'].StatusReason | [0]" \
--output text)
echo "Error: Instance Refresh failed with status: $STATUS. Reason: $REASON"
exit 1
elif [ "$STATUS" == "Pending" ]; then
echo "Instance Refresh still in Pending status... continuing to wait."
else
echo "Instance Refresh still in progress..."
fi
sleep $WAIT_INTERVAL
ELAPSED_TIME=$((ELAPSED_TIME + WAIT_INTERVAL))
done
if [ $ELAPSED_TIME -ge $MAX_WAIT ]; then
echo "Error: Instance Refresh timed out after $MAX_WAIT seconds."
exit 1
fi