Fix for deploy-ec2.yml #9
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: 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 }} | ||
- name: Ensure ECR repo exists | ||
run: | | ||
set -e | ||
aws ecr describe-repositories --repository-names "${ECR_REPOSITORY}" >/dev/null 2>&1 || \ | ||
aws ecr create-repository --repository-name "${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 }}/${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 | ||
# ---- Robust SSM deploy (POSIX /bin/sh; Ubuntu 24.04-safe) ---- | ||
- name: Deploy on EC2 via SSM | ||
env: | ||
IMAGE: ${{ steps.vars.outputs.image }} | ||
run: | | ||
set -euo pipefail | ||
cat > deploy.sh <<'EOF' | ||
#!/bin/sh | ||
set -eu | ||
# Install Docker (Ubuntu official repo for Docker CE; Amazon Linux fallback) | ||
if command -v apt-get >/dev/null 2>&1; then | ||
# Ubuntu path (no gpg; use .asc key file) | ||
export DEBIAN_FRONTEND=noninteractive | ||
apt-get update -y | ||
# remove conflicting Ubuntu docker bits (safe if absent) | ||
apt-get remove -y docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc || true | ||
apt-get install -y ca-certificates curl unzip | ||
install -m 0755 -d /etc/apt/keyrings | ||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc | ||
chmod a+r /etc/apt/keyrings/docker.asc | ||
. /etc/os-release | ||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable" > /etc/apt/sources.list.d/docker.list | ||
apt-get update -y | ||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | ||
systemctl enable --now docker || true | ||
# ECR login, pull latest, run on 80->8080 | ||
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:${APP_PORT} ${IMAGE} | ||
# Evidence | ||
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 | ||
# send via SSM without YAML/JSON escaping headaches | ||
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}" | ||
# wait and print results | ||
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" ] |