Skip to content

Commit cf8f045

Browse files
committed
Switched from SSM to SSH
1 parent 564749e commit cf8f045

File tree

1 file changed

+65
-106
lines changed

1 file changed

+65
-106
lines changed

.github/workflows/deploy-ec2.yml

Lines changed: 65 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -65,109 +65,68 @@ jobs:
6565
tags: ${{ steps.vars.outputs.image }}
6666
cache-from: type=gha
6767
cache-to: type=gha,mode=max
68-
69-
# ---- Final deploy step (fixes region expansion & non-TTY login; Ubuntu 24.04-safe) ----
70-
- name: Deploy on EC2 via SSM
71-
env:
72-
IMAGE: ${{ steps.vars.outputs.image }}
73-
run: |
74-
set -euo pipefail
75-
76-
# 1) Write a neutral script with placeholders so we can safely inject values
77-
cat > deploy.sh <<'EOF'
78-
#!/bin/sh
79-
set -eu
80-
81-
REGION="__REGION__"
82-
IMAGE="__IMAGE__"
83-
SERVICE_NAME="__SERVICE_NAME__"
84-
APP_PORT="__APP_PORT__"
85-
86-
# ---- Install Docker (Ubuntu path uses docker.asc; no gpg --dearmor / TTY) ----
87-
if command -v apt-get >/dev/null 2>&1; then
88-
export DEBIAN_FRONTEND=noninteractive
89-
apt-get update -y
90-
91-
# Remove conflicting Ubuntu docker/containerd packages (prevents "containerd.io : Conflicts: containerd")
92-
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
93-
apt-get remove -y "$pkg" || true
94-
done
95-
96-
apt-get install -y ca-certificates curl unzip
97-
install -m 0755 -d /etc/apt/keyrings
98-
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
99-
chmod a+r /etc/apt/keyrings/docker.asc
100-
. /etc/os-release
101-
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
102-
103-
apt-get update -y
104-
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
105-
106-
elif command -v dnf >/dev/null 2>&1; then
107-
dnf -y update || true
108-
dnf -y install docker curl unzip || yum -y install docker curl unzip
109-
elif command -v yum >/dev/null 2>&1; then
110-
yum -y update || true
111-
yum -y install docker curl unzip
112-
else
113-
echo "no supported package manager found"
114-
exit 1
115-
fi
116-
117-
systemctl enable --now docker || true
118-
119-
# ---- ECR login (non-interactive per AWS docs) ----
120-
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
121-
REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com"
122-
123-
aws ecr get-login-password --region "${REGION}" \
124-
| docker login --username AWS --password-stdin "${REGISTRY}"
125-
126-
# ---- Pull & run on host 80 -> container ${APP_PORT} ----
127-
docker rm -f "${SERVICE_NAME}" || true
128-
docker pull "${IMAGE}"
129-
docker run -d --restart unless-stopped --name "${SERVICE_NAME}" -p 80:"${APP_PORT}" "${IMAGE}"
130-
131-
# ---- Evidence / health check ----
132-
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'
133-
curl -sS -o /dev/null -w '%{http_code}\n' http://localhost/hello
134-
EOF
135-
chmod +x deploy.sh
136-
137-
# 2) Inject real values (this avoids single-quoted heredoc expansion issues)
138-
sed -i "s|__REGION__|${{ env.AWS_REGION }}|g" deploy.sh
139-
sed -i "s|__IMAGE__|${{ steps.vars.outputs.image }}|g" deploy.sh
140-
sed -i "s|__SERVICE_NAME__|${{ env.SERVICE_NAME }}|g" deploy.sh
141-
sed -i "s|__APP_PORT__|${{ env.APP_PORT }}|g" deploy.sh
142-
143-
# 3) Send to SSM (no YAML/JSON quoting headaches) and execute
144-
B64=$(base64 -w0 deploy.sh || base64 deploy.sh | tr -d '\n')
145-
CMD_ID=$(aws ssm send-command \
146-
--instance-ids "${EC2_INSTANCE_ID}" \
147-
--document-name "AWS-RunShellScript" \
148-
--comment "Deploy ${SERVICE_NAME}" \
149-
--parameters "commands=[\"echo ${B64} | base64 -d > /tmp/deploy.sh\",\"sudo sh /tmp/deploy.sh\"]" \
150-
--query "Command.CommandId" --output text)
151-
echo "CommandId: ${CMD_ID}"
152-
153-
# 4) Wait for completion and surface logs
154-
for i in $(seq 1 30); do
155-
STATUS=$(aws ssm get-command-invocation \
156-
--command-id "$CMD_ID" \
157-
--instance-id "${EC2_INSTANCE_ID}" \
158-
--query "Status" --output text)
159-
echo "SSM status: $STATUS"
160-
case "$STATUS" in
161-
Success) break ;;
162-
Cancelled|Failed|TimedOut) break ;;
163-
esac
164-
sleep 5
165-
done
166-
167-
aws ssm get-command-invocation \
168-
--command-id "$CMD_ID" \
169-
--instance-id "${EC2_INSTANCE_ID}" \
170-
--query "{Status:Status, StdOut:StandardOutputContent, StdErr:StandardErrorContent}" \
171-
--output text
172-
173-
[ "$STATUS" = "Success" ]
68+
- name: Deploy over SSH (no SSM)
69+
uses: appleboy/ssh-action@v1.2.1
70+
with:
71+
host: ${{ vars.EC2_PUBLIC_IP }}
72+
username: ubuntu
73+
key: ${{ secrets.EC2_SSH_KEY }}
74+
port: 22
75+
script_stop: true
76+
envs: AWS_REGION,APP_PORT,SERVICE_NAME
77+
script: |
78+
set -eu
79+
80+
REGION="${AWS_REGION}"
81+
IMAGE="${{ steps.vars.outputs.image }}"
82+
SERVICE="${SERVICE_NAME}"
83+
PORT="${APP_PORT}"
84+
85+
# --- Ensure Docker (Ubuntu 24.04-safe: remove conflicts, use Docker repo .asc key) ---
86+
if ! command -v docker >/dev/null 2>&1; then
87+
if command -v apt-get >/dev/null 2>&1; then
88+
sudo apt-get update -y
89+
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
90+
sudo apt-get remove -y "$pkg" || true
91+
done
92+
sudo apt-get install -y ca-certificates curl unzip
93+
sudo install -m 0755 -d /etc/apt/keyrings
94+
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo tee /etc/apt/keyrings/docker.asc >/dev/null
95+
sudo chmod a+r /etc/apt/keyrings/docker.asc
96+
. /etc/os-release
97+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
98+
sudo apt-get update -y
99+
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
100+
elif command -v dnf >/dev/null 2>&1; then
101+
sudo dnf -y update || true
102+
sudo dnf -y install docker curl unzip || sudo yum -y install docker curl unzip
103+
elif command -v yum >/dev/null 2>&1; then
104+
sudo yum -y update || true
105+
sudo yum -y install docker curl unzip
106+
else
107+
echo "no supported package manager found"; exit 1
108+
fi
109+
fi
110+
111+
sudo systemctl enable --now docker || true
112+
113+
# --- ECR login (non-TTY per AWS docs) ---
114+
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
115+
REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com"
116+
aws ecr get-login-password --region "$REGION" | sudo docker login --username AWS --password-stdin "$REGISTRY"
117+
118+
# --- Pull & run: host 80 -> container ${PORT} ---
119+
sudo docker rm -f "$SERVICE" || true
120+
sudo docker pull "$IMAGE"
121+
sudo docker run -d --restart unless-stopped --name "$SERVICE" -p 80:"$PORT" "$IMAGE"
122+
123+
# --- Health check w/ retries (avoid curl 56 during boot) ---
124+
for i in $(seq 1 30); do
125+
code=$(curl -sS -o /dev/null -w '%{http_code}' http://localhost/hello || true)
126+
[ "$code" = "200" ] && { echo "Health: OK (200)"; break; }
127+
echo "Health: not ready (code=${code:-none}), retrying..."
128+
sleep 3
129+
done
130+
131+
# Evidence
132+
sudo docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'

0 commit comments

Comments
 (0)