背景
GitHub ActionsからAWS(EC2・S3・Lambda)へ自動デプロイする構成を組む中で、GitHub Secretsに保存したSSH秘密鍵が原因で認証に失敗するトラブルに遭遇しました。原因と対処法、他2サービスのデプロイでのハマりどころを整理します。
1. SSH鍵の改行コード問題
Permission denied (publickey)
原因: GitHub Secretsに秘密鍵をコピー&ペーストで登録する際、改行コードが\r\n(CRLF)に変換されてしまうことがあります。SSH秘密鍵はCRLFが混入すると正しくパースできず、認証が失敗します。
対処:
run: |
echo "$SSH_KEY" | tr -d '\r' > private_key.pem
chmod 600 private_key.pem
tr -d '\r'で明示的にキャリッジリターンを除去してからファイルに書き出すことで、改行コードの混入を回避できます。
2. EC2デプロイのワークフロー全体
- name: Deploy to EC2
env:
SSH_KEY: ${{ secrets.EC2_SSH_KEY }}
HOST: ${{ secrets.EC2_HOST }}
USER: ${{ secrets.EC2_USER }}
run: |
echo "$SSH_KEY" > private_key.pem
chmod 600 private_key.pem
scp -i private_key.pem -o StrictHostKeyChecking=no -r \
server.js package.json ${USER}@${HOST}:~/myapp/
ssh -i private_key.pem -o StrictHostKeyChecking=no ${USER}@${HOST} << 'EOF'
cd ~/myapp
npm install
pm2 restart myapp || pm2 start server.js --name myapp
pm2 save
EOF
rm -f private_key.pem
pm2 restart myapp || pm2 start ...という記述で、既存プロセスがあれば再起動、なければ新規起動という初回・2回目以降を同じスクリプトで吸収する書き方をしています。デプロイ後は秘密鍵ファイルをrm -fで確実に削除するのも重要な後片付けです。
3. S3静的サイトデプロイでの403エラー
原因1: IAMユーザーに AmazonS3FullAccess がない
原因2: バケットポリシーで PublicReadGetObject が未設定
- name: Sync to S3
run: |
aws s3 sync . s3://my-github-demo-site \
--exclude ".git/*" \
--exclude ".github/*" \
--delete
--deleteオプションを付けると、S3側にあってローカルにないファイルが自動削除されます。同期の一貫性は保てますが、意図しないファイルまで消える可能性があるため、初回実行時は--dryrunで差分を確認してから本実行するのが安全です。
4. Lambdaデプロイでzipサイズが50MBを超えた場合
# 直接デプロイ(50MB制限あり)
aws lambda update-function-code \
--function-name my-function \
--zip-file fileb://function.zip
# 50MB超の場合はS3経由
aws s3 cp function.zip s3://my-bucket/
aws lambda update-function-code \
--function-name my-function \
--s3-bucket my-bucket \
--s3-key function.zip
依存パッケージが増えてzipが50MBを超えると、直接アップロードは失敗します。S3を経由するデプロイに切り替えるのが標準的な回避策です。
5. デプロイ失敗時の自動ロールバック
- name: Deploy and test
id: deploy
run: |
aws lambda update-function-code ...
if ! curl -f https://api.example.com/health; then
exit 1
fi
- name: Rollback on failure
if: failure() && steps.deploy.outcome == 'failure'
run: |
aws lambda update-function-code \
--function-name my-function \
--s3-bucket backup-bucket \
--s3-key previous-version.zip
デプロイ直後にヘルスチェックを行い、失敗したらif: failure()条件でロールバックステップを自動実行する構成です。デプロイと検証をセットにしておくことで、壊れた状態のまま本番が放置されるリスクを減らせます。
まとめ
SSH鍵の改行コード問題は初見だと原因の特定に時間がかかりますが、tr -d '\r'の1行で解決します。EC2・S3・LambdaそれぞれのデプロイパターンとIAM権限の最小化例は元記事にまとめています。