Laravelで作ったものをGitHub ActionsでEC2に自動デプロイしてみた(GitHub編)

https://qiita.com/kyona/items/5440f519df584adb529b

前回の続きになります。

## やること

GitHub
1. Secretsの設定
1. workflowの設定

## 1. Secretsの設定
1. リポジトリの[Settings]に移動しサイドメニューの[Secrets and variables]の中にある「Actions」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939352/52f808e7-2309-0151-6d00-f7c78425f513.png)

1. [New repository secret]を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939352/c0dd6bc6-cad9-0564-02a1-483a52d69bc7.png)

1. NameとSecreatを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939352/2281ec6c-bea1-1bce-e58f-c11c4f7aa26f.png)

| Name   | Secret   |
|--------|----------|
| AWS_ROLE_ARN | IAM管理画面のロールで設定したARN <br>(例:arn:aws:iam::[アカウントID]:role/[ロール名])|
| AWS_REGION    | 使用しているEC2のリージョン(例:us-east-1)      |
| INSTANCE_ID    | EC2のインスタンスID      |

## 2. workflowの設定

1. リポジトリの[Actions]に移動し「New Workflow」を押下し「set up a workflow yourself」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939352/8d2d6830-0f4f-4ff0-b7bf-5ce0ae0fba3d.png)


1. 下記を追加し「Commit changes」を行う
    ``` json:main.yml
    name: Deploy Laravel App
    
    on:
      push:
        branches:
          - main  # mainブランチへのpushをトリガー
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        permissions:
          id-token: write
          contents: read
        steps:
    
          # AWS CLIの設定
          - name: Configure AWS credentials
            uses: aws-actions/configure-aws-credentials@v3
            with:
              role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
              aws-region: ${{ secrets.AWS_REGION }}
    
          # SSMを使ってデプロイコマンドを実行
          - name: Deploy using SSM
            run: |
              response=$(aws ssm send-command \
                --instance-ids ${{ secrets.INSTANCE_ID }} \
                --document-name "AWS-RunShellScript" \
                --comment "Deploy Laravel Application" \
                --parameters '{"commands": [
                  "set -eux",
                  "export HOME=/home/ec2-user",
                  "export COMPOSER_ALLOW_SUPERUSER=1",
                  "git config --global --add safe.directory /var/www/[実行するディレクトリ]", 
                  "cd /var/www/[実行するディレクトリ]",
                  "git checkout main",
                  "git pull origin main",
                  "composer install --no-dev --optimize-autoloader",
                  "php artisan migrate --force",
                  "php artisan config:cache",
                  "php artisan route:cache",
                  "php artisan view:cache",
                  "npm install",
                  "npm run build",
                  "sudo systemctl reload nginx"
                ]}' \
                --region ${{ secrets.AWS_REGION }} \
              --output json)
    
              echo "Response from send-command: $response"
    
              # CommandIdを取得
              command_id=$(echo $response | jq -r '.Command.CommandId')
    
              # CommandIdが空でないか確認
              if [ -z "$command_id" ]; then
                echo "Error: Command ID is empty"
                exit 1
              fi
    
              # コマンド完了を待機
              aws ssm wait command-executed \
                --command-id "$command_id" \
                --instance-id ${{ secrets.INSTANCE_ID }}
              wait_status=$?
    
              if [ $wait_status -ne 0 ]; then
                echo "Waiter failed, fetching command details..."
                result=$(aws ssm get-command-invocation \
                  --command-id "$command_id" \
                  --instance-id ${{ secrets.INSTANCE_ID }} \
                  --output json)
    
                echo "Command Result:"
                echo "$result"
    
                # エラー内容を表示
                stderr=$(echo "$result" | jq -r '.StandardErrorContent')
                echo "---- Standard Error ----"
                echo "$stderr"
    
                exit 1
              fi
    
              echo "Command execution completed successfully."
    
              # $command_id を後続ステップで使えるようエクスポート
              echo "COMMAND_ID=$command_id" >> $GITHUB_ENV
    
          # エラー詳細と標準出力を表示
          - name: Handle SSM Command Execution Result
            run: |
              # 結果を取得2
              result=$(aws ssm get-command-invocation \
                --command-id "$COMMAND_ID" \
                --instance-id ${{ secrets.INSTANCE_ID }} \
                --output json)
    
              # ステータスを取得
              status=$(echo "$result" | jq -r '.Status')
    
              echo "Command Status: $status"
    
              # 標準出力を取得
              stdout=$(echo "$result" | jq -r '.StandardOutputContent')
    
              echo "---- Standard Output ----"
              echo "$stdout"
    
              # ステータスがFailedの場合はエラーを返す
              if [ "$status" == "Failed" ]; then
                echo "Command execution failed."
                exit 1
              fi
    
              echo "Command executed successfully."
              
    ```

    **AWS_ROLE_ARN**等は[1. Secretsの設定]で設定した名前に合わせてください。
    send-commandは実行できたけどアプリが反映されない事象が起こったのでログを出力するようにしました。
    ログ表示はいらないよーという方は「# コマンド完了を待機」から下を削除してください。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939352/f2a31f99-73ed-9518-a60f-75bb9fd50bc6.png)

1. [Actions]に移動し実行されているか、エラーがないか確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939352/23fefc76-1661-fefd-ded3-58a1f0db9333.png)

    全てにチェックをがついていたら問題ありません。
    バツマークがあればそこの部分を押下して内容を確認してください。
    ![スクリーンショット 2024-11-25 16.29.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939352/bc9dd766-4791-faef-4833-890f2e41b78c.png)

ありがとうございました。