LoginSignup
2
0

Google Cloud Secret ManagerとGitHub Actionsを連携させた環境変数の管理

Last updated at Posted at 2023-06-23
  • GitHub Actionsのワークフローを利用しているプロジェクトで、GCPのSecret Managerを使って環境変数を一元管理したいと思いました。しかし、GCPのSecret Managerから秘密情報を取得する際に「403 Permission Denied」エラーに遭遇しました。
  • けっこう悩んだ末わかったのは、GCPの仕様として、自前で用意したサービスアカウントへSecret Managerへのアクセス権限を付与しても無効かもということでした。解決策として、デフォルトのサービスアカウントへ、自前のサービスアカウントを紐付けることで問題が解消しました。

Google Cloudの認証の仕組み

今回は、GitHub Actionsの設定ファイル(Yaml)で、認証用JSONファイルを読み込むことでGoogle認証を行い、Secret Managerへ環境変数を適用する仕組みにしました。

# 省略...

      - id: 'auth'
        name: 'Authenticate to Google Cloud'
        uses: 'google-github-actions/auth@v1'
        with:
          credentials_json: '${{ secrets.GCLOUD_CREDENTIAL }}'

# 省略...

      - name: Configure dotenv file
        # load envs from github secrets
        run: |
          cat << EOF > .env
          # 省略(環境変数の定義)...
          EOF
      - name: Run a new version of secrets
        run: |
          gcloud secrets versions add ${{ secrets.GCLOUD_SECRET_LABEL }} --data-file .env

そして認証ファイルで認証する自前のサービスアカウントには、PythonでGcloudのAPIを使うための権限(Secret Manager周りや、コンテナ管理のためのArtifact Registry周り、CloudStorageなど)を付与しておきました。

ちなみにPythonコードでは、ENVファイルの中身がGCPのSecret Managerから取得されます(下記、payload変数を作る箇所)

# 省略...

def get_google_secret_payload(secret_label, version) -> str | None:
    try:
        _, project_id = google.auth.default()
    except google.auth.exceptions.DefaultCredentialsError:
        project_id = None
    if project_id is None:
        return None

    # 省略...

    client = secretmanager.SecretManagerServiceClient()
    gcloud_secret_name = (
        f"projects/{project_id}/secrets/{secret_label}/versions/{version}"
    )
    payload = client.access_secret_version(name=gcloud_secret_name).payload.data.decode(
        "UTF-8"
    )
    return payload

# 省略...

問題の原因

これを動かした結果、エラー「google.api_core.exceptions.PermissionDenied: 403 Permission 'secretmanager.versions.access' denied for resource 'projects/***project/secrets/env_file/versions/latest' (or it may not exist)."」が発生して、Secret Managerから秘密情報を取得できず、、Secret Manager周りの権限を管理者権限にしても、同じでした。

その原因は、コードが動くCloudRun環境(今回私はCloudRunへのデプロイを行いました)がデフォルトで別のサービスアカウント(サービスアカウント「***-compute@developer.gserviceaccount.com」)を使用して認証するようになっているようであり、そのアカウントがSecret Managerへの適切なアクセス権限を持っていなかったためです。

解決策

デフォルトのサービスアカウントに「Secret Managerのシークレットアクセサー」ロールを付与し、

image.png

さらに自前のサービスアカウントにデフォルトのサービスアカウントユーザーへのアクセス権限を付与。
image.png

これにより、デフォルトのサービスアカウントを介してカスタムサービスアカウントの権限でSecret Managerにアクセスすることが可能になりました。バンザイ

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0