🎭

[Playwright] CI/CDで社内環境に対してGitHub ActionsのIPを許可する in GCP編

2024/11/26に公開

はじめに

この記事では、社内で初めてCI/CDに組み込む時に苦労した点と対策を解説します。

実際に使ったyaml
name: Playwright Tests

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  e2e-tests:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
    - uses: actions/checkout@v4
    - uses: google-github-actions/auth@v2
      with:
        workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
        service_account: 'example@project.iam.gserviceaccount.com'

    # GitHub ActionsのIPは可変のため、GitHub Actionsのアクセスを許可するルールをWAFに追加する
    - name: Allow Security-Policy
      run: |
        IP=$(curl -f -s http://whatismyip.akamai.com)
        echo "The IP address is: $IP"
        gcloud compute security-policies rules create NUMBER --action allow --security-policy XXXXX --description "GitHub Actions IP" --src-ip-ranges ${IP}

    - uses: actions/setup-node@v4
      with:
        node-version: 18
        cache: npm
        cache-dependency-path: package-lock.json
    - name: Install dependencies
      run: npm ci

    - name: Install Playwright Browsers
      run: npx playwright install --with-deps

    # WAFのルールが適応に時間が必要なため待機する
    - name: Wait for WAF to apply (up to 3 minutes)
      run: |
        sleep 90
        for i in {1..3}; do
          if curl -f https://example.com; then
            echo "Success"
            break
          fi
          echo "Retrying in 30 seconds..."
          sleep 30
        done

    # テスト実行
    - name: Run Playwright tests
      run: npx playwright test

    # 先ほど追加したWAFの許可ルールを削除する
    - name: Delete Security-Policy
      if: ${{ always() }}
      run: |
        gcloud compute security-policies rules delete NUMBER --security-policy XXXXX --quiet

1. google-github-actions/authのエラーが解消できない

このエラーを解消するのに大変時間を要しました。

上記のエラーを解消する時に試したことを列挙します。
お困りの方は、ご参考になれば幸いです。

1. id-tokenの書き込み権限を許可する

当時 id-tokenの書き込み権限を許可しても上記のエラーは解消しませんでした。

jobs:
  e2e-tests:
    runs-on: ubuntu-latest
+    # Add "id-token" with the intended permissions.
+    permissions:
+      id-token: write
+      contents: read
    steps:

2. google-github-actions/authの書き方が正しいか

下記項目について確認しました。

  • google-github-actions/authのver
  • workload_identity_providerの値
  • service_accountの値
- uses: google-github-actions/auth@v2
  with:
    workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
    service_account: 'example@project.iam.gserviceaccount.com'

3. 対象レポジトリーのSettingsが適切か

下記項目にチェックが付いているのかを確認しました。

  • Fork pull request workflows > Run workflows from fork pull requests
  • Workflow permissions > Read and write permissions

gihub-setting

4. service_accountをCLIから作成する

当初はGUIからservice_accountを作成しておりましたが、CLIで実行すると必要な設定ができるみたいです。
下記URLが参考サイトみたいです。

※インフラ担当の方に依頼したので詳細はよく分かりません。

5. google-github-actions/authの前にactions/checkoutを追加する

下記サイトを参考にactions/checkoutを追加しましたが、解消には繋がりませんでした。

+ - uses: actions/checkout@v4
  - uses: google-github-actions/auth@v2
    with:
      workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
      service_account: 'example@project.iam.gserviceaccount.com'

6. Fork先から実行するのではなく、Fork元から実行する

この対応でgoogle-github-actions/authのエラーが解消されました。

2. WAFが有効になるのに時間がかかる

当たり前の話かもしれませんが、WAFは即座反映されません。
そのため、WAF設定が有効になるのを待つ必要があります。

方法はいくつかあるとおもいますが、自分は下記コードをyamlに追加しました。
※ 大体1-3分の間で有効になることを観測しております。

# WAFのルールが適応に時間が必要なため待機する
- name: Wait for WAF to apply (up to 3 minutes)
  run: |
    sleep 90
    for i in {1..3}; do
      if curl -f https://example.com; then
        echo "Success"
        break
      fi
      echo "Retrying in 30 seconds..."
      sleep 30
    done

3. JobごとでGithub ActionsのIPが変わる

当初は各Jobを管理しやすいように細かく分けましたが、各JobでIPが変わります。
そのため、allow-security-policyで許可したIP以外でPlaywrightが実行されて403 Forbiddenが表示されて困りました。
しかし、下記サイトを読み各Jobを1つにまとめ403 Forbiddenを解消しました。

下記のようにyamlを変更しました。

jobs:
-  allow-security-policy:
-    runs-on: ubuntu-latest
-    steps:
-    # --- 以下略 ---
-
-  run-playwright-tests
-    runs-on: ubuntu-latest
-    steps:
-    # --- 以下略 ---
-
-  delete-security-policy
-    runs-on: ubuntu-latest
-    steps:
-    # --- 以下略 ---

+  e2e-tests:
+    runs-on: ubuntu-latest
+    steps:
+    # --- 以下略 ---

4. 海外アクセスブロックよりも優先度を高くする

既存のWAFのルールに国内以外からのアクセスは拒否のルールがありました。
Githubは海外になるため、上記のルールよりも優先度を高くする必要があります。

5. Playwrightのために追加したWAFのルールは必ず削除する

試行錯誤中は最後まで処理を進まないケースがあります。
その時、前回のWAFのルールが残ったまま下記のエラーが発生しておりました。
※ そのたびにインフラ担当の方に削除連絡をしておりました。

if: ${{ always() }}を追加しテストの失敗/キャンセル/処理の失敗でも必ず削除処理を実行する必要があります。

    # 先ほど追加したWAFの許可ルールを削除する
    - name: Delete Security-Policy
+      if: ${{ always() }}
      run: |
        gcloud compute security-policies rules delete NUMBER --security-policy XXXXX --quiet

6. 連続でCI/CDはできない

WAFの優先度を固定の数値にしているため、priorityの重複エラーが発生します。
再度確認したい場合は、前回の処理が終わるのを待つ or キャンセルする必要があります。

GitHubで編集を提案

Discussion