AWS CDK で作成した Secrets Manager シークレットを GitHub Actions で aws-actions/aws-secretsmanager-get-secrets を使用して環境変数に設定する

AWS CDK で作成した Secrets Manager シークレットを GitHub Actions で aws-actions/aws-secretsmanager-get-secrets を使用して環境変数に設定する

Clock Icon2025.06.16

こんにちは、製造ビジネステクノロジー部の若槻です。

システムのテストにはいくつか種類がありますが、実際のシステムに接続する Integration テスト(E2E テスト)を GitHub Actions 上で実行したい場合に 、API への接続情報や AWS リソースの ARN などの情報をワークフロー内で環境変数として参照したいことがあると思います。しかし参照するべき値が増えていくと、そのたびにワークフローファイルを修正する手間が発生したり、設定忘れが起きやすくなったりしてしまいます。

そのような場合におすすめなのが aws-actions/aws-secretsmanager-get-secrets という AWS 公式アクションです。このアクションを使用すると、GitHub Actions ワークフロー内で参照したい環境変数の管理を AWS Secrets Manager シークレットに集約し、運用を簡素化することが可能になります。

https://github.com/aws-actions/aws-secretsmanager-get-secrets

今回は、AWS CDK で作成した Secrets Manager シークレットを GitHub Actions で aws-actions/aws-secretsmanager-get-secrets を使用して取得し、環境変数に設定する方法を紹介します。

やってみた

AWS CDK 実装

まず、必要な AWS リソースを AWS CDK で実装します。以下のコードでは、2つの Secrets Manager シークレットと GitHub Actions OIDC ロールを作成しています。

lib/main-stack.ts
import * as cdk from "aws-cdk-lib";
import * as iam from "aws-cdk-lib/aws-iam";
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
import { Construct } from "constructs";

export class MainStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    const awsAccountId = cdk.Stack.of(this).account;
    const githubOrganizationName = process.env.GITHUB_ORGANIZATION_NAME || "";
    const githubRepositoryName = process.env.GITHUB_REPOSITORY_NAME || "";

    /**
     * Secrets Manager シークレット 1 の作成
     */
    const secret1 = new secretsmanager.Secret(this, "Secret1", {
      secretObjectValue: {
        api_user: cdk.SecretValue.unsafePlainText("user_hoge_"),
        api_key: cdk.SecretValue.unsafePlainText("key_fuga_"),
        config: cdk.SecretValue.unsafePlainText(
          JSON.stringify({ active: "user2_piyo_", standby: "user3_nyan_" })
        ),
      },
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
    new cdk.CfnOutput(this, "Secret1ArnOutput", {
      value: secret1.secretArn,
      description:
        "Specify this output value with the aws-actions/aws-secretsmanager-get-secret action to get the value of the secret1.",
    });

    /**
     * Secrets Manager シークレット 2 の作成
     */
    const secret2 = new secretsmanager.Secret(this, "Secret2", {
      secretObjectValue: {
        myusername: cdk.SecretValue.unsafePlainText("alejandro_rosalez_"),
        mypassword: cdk.SecretValue.unsafePlainText("EXAMPLE_PASSWORD_"),
      },
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
    new cdk.CfnOutput(this, "Secret2ArnOutput", {
      value: secret2.secretArn,
      description:
        "Specify this output value with the aws-actions/aws-secretsmanager-get-secret action to get the value of the secret2.",
    });

    /**
     * GitHub Actions OIDC ロールの作成
     */
    const gitHubActionsOidcRole = new iam.Role(this, "GitHubActionsOidcRole", {
      assumedBy: new iam.FederatedPrincipal(
        `arn:aws:iam::${awsAccountId}:oidc-provider/token.actions.githubusercontent.com`,
        {
          StringEquals: {
            "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
          },
          StringLike: {
            "token.actions.githubusercontent.com:sub": `repo:${githubOrganizationName}/${githubRepositoryName}:*`,
          },
        },
        "sts:AssumeRoleWithWebIdentity"
      ),
    });
    new cdk.CfnOutput(this, "GitHubActionsOidcRoleArnOutput", {
      value: gitHubActionsOidcRole.roleArn,
      description:
        "Specify this output value with the aws-actions/configure-aws-credentials action to assume the role.",
    });

    /**
     * GitHub Actions OIDC ロールに Secrets Manager シークレットの読み取り権限を付与
     */
    secret1.grantRead(gitHubActionsOidcRole);
    secret2.grantRead(gitHubActionsOidcRole);
  }
}

シークレット作成時のポイントとして、secretObjectValue プロパティを使用して、シークレットの値をオブジェクトとして定義しています。これにより、シークレットの値を JSON 形式の階層で管理でき、また後述の GitHub Actions ワークフローでも個別の環境変数として展開することが可能になります。

上記実装を AWS CDK でデプロイします。

GitHub Environments の設定

前述の CDK 実装をデプロイすると出力されるリソースの ARN を GitHub Environments の変数として以下の通り登録します。

変数名
ROLE_TO_ASSUME_ARN GitHubActionsOidcRole の ARN
SECRET1_ARN Secret1 の ARN
SECRET2_ARN Secret2 の ARN

GitHub Actions ワークフロー

aws-actions/aws-secretsmanager-get-secrets アクションを使用して Secrets Manager シークレットの値を取得し、環境変数に設定する GitHub Actions ワークフローを作成します。

.github/workflows/secret-retrieve-test.yml
name: SECRET_RETRIEVE_TEST

on: workflow_dispatch

jobs:
  get-secrets:
    environment: DEVELOPMENT
    runs-on: ubuntu-latest
    permissions:
      # @see https://github.com/aws-actions/configure-aws-credentials?tab=readme-ov-file#oidc
      id-token: write
      contents: read

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      # AWS 認証情報を設定
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ vars.ROLE_TO_ASSUME_ARN }} # CDK で作成した GitHubActionsOidcRole の ARN
          aws-region: ap-northeast-1 # AWS リージョン

      # Secret1 と Secret2 の値を取得して環境変数に設定
      - name: Get secrets from AWS Secrets Manager
        uses: aws-actions/aws-secretsmanager-get-secrets@v2
        with:
          secret-ids: |
            SECRET1,${{ vars.SECRET1_ARN }}
            SECRET2,${{ vars.SECRET2_ARN }}
          parse-json-secrets: true # JSONを解析して個別の環境変数に設定

      # 環境変数を使用するサンプルタスク(マスクされないように末尾1文字を削って出力)
      - name: Use environment variables in a task
        run: |
          echo "${SECRET1_API_USER%?}"
          echo "${SECRET1_API_KEY%?}"
          echo "${SECRET1_CONFIG_ACTIVE%?}"
          echo "${SECRET1_CONFIG_STANDBY%?}"
          echo "${SECRET2_MYUSERNAME%?}"
          echo "${SECRET2_MYPASSWORD%?}"

AWS 認証さえ行われていれば、シークレットの ARN を指定するだけで、aws-actions/aws-secretsmanager-get-secrets アクションが Secrets Manager からシークレットの値を取得し、環境変数に設定してくれます。また環境変数名の形式は SECRET1_API_USER のように、シークレット名とキー名をアンダースコアで連結した形式になります。

動作確認

ワークフローを実行すると、以下のように Secrets Manager シークレットの値が環境変数として設定されていることが確認できました。

Run echo "${SECRET1_API_USER%?}"
  echo "${SECRET1_API_USER%?}"
  echo "${SECRET1_API_KEY%?}"
  echo "${SECRET1_CONFIG_ACTIVE%?}"
  echo "${SECRET1_CONFIG_STANDBY%?}"
  echo "${SECRET2_MYUSERNAME%?}"
  echo "${SECRET2_MYPASSWORD%?}"
  shell: /usr/bin/bash -e {0}
  env:
    AWS_DEFAULT_REGION: ap-northeast-1
    AWS_REGION: ap-northeast-1
    AWS_ACCESS_KEY_ID: ***
    AWS_SECRET_ACCESS_KEY: ***
    AWS_SESSION_TOKEN: ***
    SECRET1_API_KEY: ***
    SECRET1_API_USER: ***
    SECRET1_CONFIG_ACTIVE: ***
    SECRET1_CONFIG_STANDBY: ***
    SECRET2_MYPASSWORD: ***
    SECRET2_MYUSERNAME: ***
    SECRETS_LIST_CLEAN_UP: ["SECRET1_API_KEY","SECRET1_API_USER","SECRET1_CONFIG_ACTIVE","SECRET1_CONFIG_STANDBY","SECRET2_MYPASSWORD","SECRET2_MYUSERNAME"]
user_hoge
key_fuga
user2_piyo
user3_nyan
alejandro_rosalez
EXAMPLE_PASSWORD

ハマった箇所

アクションのドキュメントによると、デバッグログの有効化で環境変数の値が出力されるようになるとのこと。先ほどは環境変数の値がマスクされないように末尾1文字を削る工夫をしていましたが、これを使えば値をそのまま出力できるのではないかと当初考えました。

https://github.com/aws-actions/aws-secretsmanager-get-secrets/blob/main/README.md#use-aws-secrets-manager-secrets-in-github-jobs

To view the environment variables created from your secrets, turn on debug logging. For more information, see Enabling debug logging in the GitHub Docs.

デバッグログの有効化ドキュメントを参考に GitHub Environments にてデバッグログを有効化してみました。

変数名
ACTIONS_RUNNER_DEBUG true
ACTIONS_STEP_DEBUG true

しかし、デバッグログにも、もちろん実際の出力にも環境変数の値が出てこずマスクされたままです...。

::add-mask::***
##[debug]Injecting secret SECRET1 as environment variable 'SECRET1_API_KEY'.
::add-mask::***
##[debug]Injecting secret SECRET1 as environment variable 'SECRET1_API_USER'.
::add-mask::***
##[debug]Injecting secret SECRET1 as environment variable 'SECRET1_CONFIG_ACTIVE'.
::add-mask::***
##[debug]Injecting secret SECRET1 as environment variable 'SECRET1_CONFIG_STANDBY'.
::add-mask::***
##[debug]Injecting secret SECRET2 as environment variable 'SECRET2_MYUSERNAME'.
::add-mask::***
##[debug]Injecting secret SECRET2 as environment variable 'SECRET2_MYPASSWORD'.


やり方が悪いのか仕様なのか今回は上手くいきませんでした。同様のデバッグを考えている方は注意するようにしましょう。

おわりに

AWS CDK で作成した Secrets Manager シークレットを GitHub Actions で aws-actions/aws-secretsmanager-get-secrets を使用して取得し、環境変数に設定する方法を紹介しました。

どなたかの参考になれば幸いです。

以上

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.