@@ -66,39 +66,43 @@ jobs:
66
66
cache-from : type=gha
67
67
cache-to : type=gha,mode=max
68
68
69
- # ---- Robust SSM deploy (POSIX /bin/sh ; Ubuntu 24.04-safe) ----
69
+ # ---- Final deploy step (fixes region expansion & non-TTY login ; Ubuntu 24.04-safe) ----
70
70
- name : Deploy on EC2 via SSM
71
71
env :
72
72
IMAGE : ${{ steps.vars.outputs.image }}
73
73
run : |
74
74
set -euo pipefail
75
-
76
- # Write the remote script locally (heredoc), then base64 it to avoid YAML/JSON escaping issues.
75
+
76
+ # 1) Write a neutral script with placeholders so we can safely inject values
77
77
cat > deploy.sh <<'EOF'
78
78
#!/bin/sh
79
79
set -eu
80
-
81
- # -------- Install Docker (Ubuntu path uses docker.asc; no gpg --dearmor) --------
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) ----
82
87
if command -v apt-get >/dev/null 2>&1; then
83
88
export DEBIAN_FRONTEND=noninteractive
84
89
apt-get update -y
85
-
86
- # Remove conflicting Ubuntu packages to avoid "containerd.io : Conflicts: containerd"
90
+
91
+ # Remove conflicting Ubuntu docker/containerd packages (prevents "containerd.io : Conflicts: containerd")
87
92
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
88
93
apt-get remove -y "$pkg" || true
89
94
done
90
-
95
+
91
96
apt-get install -y ca-certificates curl unzip
92
97
install -m 0755 -d /etc/apt/keyrings
93
98
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
94
99
chmod a+r /etc/apt/keyrings/docker.asc
95
100
. /etc/os-release
96
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
97
-
102
+
98
103
apt-get update -y
99
104
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
100
-
101
- # -------- Amazon Linux / RHEL family fallback --------
105
+
102
106
elif command -v dnf >/dev/null 2>&1; then
103
107
dnf -y update || true
104
108
dnf -y install docker curl unzip || yum -y install docker curl unzip
@@ -109,40 +113,44 @@ jobs:
109
113
echo "no supported package manager found"
110
114
exit 1
111
115
fi
112
-
116
+
113
117
systemctl enable --now docker || true
114
-
115
- # -------- ECR login, pull latest, run on 80 -> ${APP_PORT} ---- ----
118
+
119
+ # ---- ECR login (non-interactive per AWS docs) ----
116
120
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
117
- REGION='${AWS_REGION}'
118
121
REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com"
119
-
122
+
120
123
aws ecr get-login-password --region "${REGION}" \
121
124
| docker login --username AWS --password-stdin "${REGISTRY}"
122
-
123
- docker rm -f ${SERVICE_NAME} || true
124
- docker pull ${IMAGE}
125
- docker run -d --restart unless-stopped --name ${SERVICE_NAME} -p 80:${APP_PORT} ${IMAGE}
126
-
127
- # -------- Evidence / health check --------
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 ----
128
132
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'
129
133
curl -sS -o /dev/null -w '%{http_code}\n' http://localhost/hello
130
134
EOF
131
135
chmod +x deploy.sh
132
-
133
- # Send to SSM (two simple commands) and execute
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
134
144
B64=$(base64 -w0 deploy.sh || base64 deploy.sh | tr -d '\n')
135
-
136
145
CMD_ID=$(aws ssm send-command \
137
146
--instance-ids "${EC2_INSTANCE_ID}" \
138
147
--document-name "AWS-RunShellScript" \
139
148
--comment "Deploy ${SERVICE_NAME}" \
140
149
--parameters "commands=[\"echo ${B64} | base64 -d > /tmp/deploy.sh\",\"sudo sh /tmp/deploy.sh\"]" \
141
150
--query "Command.CommandId" --output text)
142
-
143
151
echo "CommandId: ${CMD_ID}"
144
-
145
- # Wait for completion and surface logs
152
+
153
+ # 4) Wait for completion and surface logs
146
154
for i in $(seq 1 30); do
147
155
STATUS=$(aws ssm get-command-invocation \
148
156
--command-id "$CMD_ID" \
@@ -155,11 +163,11 @@ jobs:
155
163
esac
156
164
sleep 5
157
165
done
158
-
166
+
159
167
aws ssm get-command-invocation \
160
168
--command-id "$CMD_ID" \
161
169
--instance-id "${EC2_INSTANCE_ID}" \
162
170
--query "{Status:Status, StdOut:StandardOutputContent, StdErr:StandardErrorContent}" \
163
171
--output text
164
-
172
+
165
173
[ "$STATUS" = "Success" ]
0 commit comments