Fix for deploy-ec2.yml #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: ci-deploy-ec2 | ||
on: | ||
push: | ||
branches: [ gopi-dev ] | ||
permissions: | ||
id-token: write | ||
contents: read | ||
env: | ||
AWS_REGION: ${{ vars.AWS_REGION || 'us-east-1' }} | ||
ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY || 'careerforge' }} | ||
EC2_INSTANCE_ID: ${{ vars.EC2_INSTANCE_ID }} | ||
APP_PORT: "8080" | ||
SERVICE_NAME: "careerforge" | ||
jobs: | ||
build-push-deploy: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up JDK 21 | ||
uses: actions/setup-java@v4 | ||
with: | ||
distribution: temurin | ||
java-version: '21' | ||
cache: maven | ||
- name: Unit tests | ||
working-directory: code/backend | ||
run: mvn -B -ntp test | ||
- name: Configure AWS credentials (OIDC) | ||
uses: aws-actions/configure-aws-credentials@v4 | ||
with: | ||
role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} | ||
aws-region: ${{ env.AWS_REGION }} | ||
- run: aws sts get-caller-identity | ||
- name: Ensure ECR repo exists | ||
run: | | ||
aws ecr describe-repositories --repository-names "${{ env.ECR_REPOSITORY }}" >/dev/null 2>&1 || \ | ||
aws ecr create-repository --repository-name "${{ env.ECR_REPOSITORY }}" | ||
- name: Login to ECR | ||
id: login-ecr | ||
uses: aws-actions/amazon-ecr-login@v2 | ||
- name: Compute image tag | ||
id: vars | ||
run: | | ||
echo "image=${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ github.sha }}" >> $GITHUB_OUTPUT | ||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v3 | ||
- name: Build and push image | ||
uses: docker/build-push-action@v6 | ||
with: | ||
context: code/backend | ||
file: code/backend/Dockerfile | ||
push: true | ||
tags: ${{ steps.vars.outputs.image }} | ||
cache-from: type=gha | ||
cache-to: type=gha,mode=max | ||
- name: Deploy on EC2 via SSM (robust, POSIX; installs AWS CLI v2 bundle) | ||
env: | ||
IMAGE: ${{ steps.vars.outputs.image }} | ||
run: | | ||
set -euo pipefail | ||
cat > deploy.sh <<'EOF' | ||
#!/bin/sh | ||
set -eu | ||
# ---- Install Docker (Ubuntu or Amazon Linux) ---- | ||
if command -v apt-get >/dev/null 2>&1; then | ||
# APT path (Ubuntu 24.04) | ||
export DEBIAN_FRONTEND=noninteractive | ||
apt-get update -y | ||
# 1) Remove Ubuntu-packaged docker bits that conflict | ||
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do | ||
apt-get remove -y "$pkg" || true | ||
done | ||
# 2) Add Docker's official repository | ||
apt-get install -y ca-certificates curl gnupg | ||
install -m 0755 -d /etc/apt/keyrings | ||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg | ||
chmod a+r /etc/apt/keyrings/docker.gpg | ||
. /etc/os-release | ||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ | ||
https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable" > /etc/apt/sources.list.d/docker.list | ||
# 3) Install Docker Engine + containerd.io from Docker's repo | ||
apt-get update -y | ||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | ||
# 4) Start Docker | ||
systemctl enable --now docker | ||
# ---- ECR login, pull, run ---- | ||
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) | ||
REGION='${AWS_REGION}' | ||
REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com" | ||
aws ecr get-login-password --region "${REGION}" | docker login --username AWS --password-stdin "${REGISTRY}" | ||
docker rm -f ${SERVICE_NAME} || true | ||
docker pull ${IMAGE} | ||
docker run -d --restart unless-stopped --name ${SERVICE_NAME} -p 80:8080 ${IMAGE} | ||
# ---- Evidence / health check ---- | ||
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}' | ||
curl -sS -o /dev/null -w '%{http_code}\n' http://localhost/hello | ||
EOF | ||
chmod +x deploy.sh | ||
B64=$(base64 -w0 deploy.sh || base64 deploy.sh | tr -d '\n') | ||
CMD_ID=$(aws ssm send-command \ | ||
--instance-ids "$EC2_INSTANCE_ID" \ | ||
--document-name "AWS-RunShellScript" \ | ||
--comment "Deploy ${SERVICE_NAME}" \ | ||
--parameters "commands=[\"echo $B64 | base64 -d > /tmp/deploy.sh\",\"sudo sh /tmp/deploy.sh\"]" \ | ||
--query "Command.CommandId" --output text) | ||
echo "CommandId: $CMD_ID" | ||
for i in $(seq 1 30); do | ||
STATUS=$(aws ssm get-command-invocation \ | ||
--command-id "$CMD_ID" \ | ||
--instance-id "$EC2_INSTANCE_ID" \ | ||
--query "Status" --output text) | ||
echo "SSM status: $STATUS" | ||
case "$STATUS" in | ||
Success) break ;; | ||
Cancelled|Failed|TimedOut) break ;; | ||
esac | ||
sleep 5 | ||
done | ||
aws ssm get-command-invocation \ | ||
--command-id "$CMD_ID" \ | ||
--instance-id "$EC2_INSTANCE_ID" \ | ||
--query "{Status:Status, StdOut:StandardOutputContent, StdErr:StandardErrorContent}" \ | ||
--output text | ||
[ "$STATUS" = "Success" ] | ||