Amplify Hostingのプレビュー環境でパラメータストアの秘匿情報を取得する

ROUTE06 でソフトウェアエンジニアをしている @MH4GF です。
私が関わるプロダクトでは、Amplify HostingでViteを利用したSPAをホスティングしています。今回秘匿情報を安全に設定する方法に詰まったため、解決方法を共有します。

TL;DR

  • Amplify Hostingの組み込みのパラメータストア連携では制約上使えなかったため、ビルドステップでAWS CLIで取得することにした
  • サービスロールにパラメータストアの読み取り権限を付与する必要がある

Amplify Hosting公式のパラメータストア連携

Amplify Hostingで環境変数として秘匿情報を扱いたい場合、パラメータストアのSecureString経由で設定することが公式ドキュメントで推奨されています。

Don't use environment variables to store secrets. Store secrets in an environment secret created using the AWS Systems Manager Parameter Store. For more information, see Environment secrets.

docs.aws.amazon.com

Amplify Hostingの組み込みの機能として、ビルド時に /amplify/{your_app_id}/{your_backend_environment_name}/{your_parameter_name} という命名規則のパラメータをパラメータストアから取得し $secrets という変数にJSONとして格納する機能があります。Node.js環境下では process.env.secrets['your_parameter_name'] から参照できます。

この your_backend_environment_name は何かというと、接続しているブランチ名となります。例えば main ブランチに接続している場合は /amplify/xxxxxxxxxxxxxx/main/GITHUB_TOKEN といった形でパラメータを保存します。

ただ私たちのプロダクトではAmplify Hostingのデフォルトのプレビュー機能を事情により利用しておらず、GitHub Actions経由でPull Requestごとにブランチを接続(== 環境を作成)しています。 そのため your_backend_environment_name に指定するブランチが一意ではないため、この機能を利用することができませんでした。

GitHub Actions経由でのAmplify Hostingのプレビューについては以下で解説しています。

tech.route06.co.jp

別の方法を探してAmplify Hostingのissueを見ていると、ビルドステップでAWS CLIでパラメータを取得する方法が紹介されていました。

github.com

これであれば比較的柔軟にパラメータを取得できそうです。

ビルドステップでAWS CLIでパラメータを取得する

最終的にはamplify.ymlは以下のようになりました。

version: 1
frontend:
  phases:
    preBuild:
      commands:
        # 秘匿情報を.envに出力する。/amplify/my-app/.envは任意のキー
        - echo $(aws ssm get-parameter --name /amplify/my-app/.env --query Parameter.Value --output text --with-decryption) >> .env
    build:
      commands:
        # vite buildの実行
        - npm run build
  artifacts:
    baseDirectory: dist
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

preBuildで秘匿情報を取得し、.envに出力します。私たちのプロダクトはViteでビルドしており、Viteは組み込みで.envを読み込んでくれるため、それに任せます。
パラメータストアに保存している.envの文字列は、改行で複数のkey/valueを指定しています。更新したい場合は取り急ぎAWSコンソール上でパラメータを更新する運用としています。できればIaC化したいですが、コンソール上で履歴が残るため良しとし今のところはこれで運用しています。

また、サービスロールにパラメータストアの読み取り権限を付与する必要があります。これはAmplify Hostingのビルドステップはサービスロールで実行されるためです。以下のようなIAMポリシーをサービスロールにアタッチしています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeParameters",
                "ssm:GetParametersByPath",
                "ssm:GetParameters",
                "ssm:GetParameter"
            ],
            "Resource": "*" // 適切に絞るのが望ましいです
        }
    ]
}

参考