AWS
Apex
lambda

APEXでLambdaのデプロイ環境を分離する


はじめに

APEXでLambda関数のリソースをデプロイ環境ごとに切り分ける方法について、個人的に良いとおもう方法をまとめました。


要件


  1. デプロイ環境ごとに異なるAWSアカウントを利用する

  2. デプロイ環境ごとに異なる環境変数を設定する

  3. ソースコードリポジトリにアップロードしたくないような秘密情報については、2とは別に管理する

  4. Lambdaソースコード自体はデプロイ環境にかかわらず同一にする

要件1について、StagingとProductionで同一のAWSアカウントを利用する場合もあると思いますが、AWSアカウントを独立させるほうがリソースの分離が徹底されます。私が関わったプロジェクトでもおもに要件1の構成を採用しています。

APEXで標準で用意されている方法を使えば要件4は自動的に満たされるので、以下では次の2つの観点で記述します

要件1 => AWSアカウントの分離について

要件2, 3 => 環境変数の分離について


AWSアカウントの分離について

APEX で AWS の Credentialsを指定する方法は次の2つがあります。


  1. 環境変数を利用する方法


  2. ~/.aws ファイルを利用する方法

デプロイ環境ごとにディレクトリスを分けられる場合は、direnvを使ってディレクトリごとに環境設定をスイッチすることができます。

しかし、APEXだと環境設定ファイルを project.production.json のような名前で同じディレクトリに配置していくことになるので、1の方法は使えません。

したがって、今回は2の方法を採用します。


デプロイ環境ごとにProfileを用意する

デプロイ環境ごとにプロファイルを用意します。

なお、意図しないCredentialsを使ってリソースを作成されてしまうリスクがあるので、(特に複数のプロジェクトでCredentialsを使い分けている場合など)基本的には defaultのプロファイルは設定しないほうが良いと思います。


~/.aws/credentials

[staging]

aws_access_key_id = xxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxx
[production]
aws_access_key_id = xxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxx


project.*.json にprofileを指定する

デプロイするときのprofileを指定する方法には次の2通りの方法があります:


  1. apex コマンドのオプション --profile で指定する


  2. project.*.json で指定する

環境ごとの設定を指定する場所をなるべく1箇所に集約したいので、今回は2の方法を採用します。1の方法だとデプロイ時に apex deploy --profile=staging --env=staging のようなコマンドを打つ必要があり、環境を指定する部分が冗長になってしまいます。


project.staging.json

{

"profile": "staging"
}


project.production.json

{

"profile": "production"
}


環境変数の分離について

パスワードなど、GitHubなどのソースコードリポジトリにアップロードするとまずい情報は通常の環境変数とは別で管理します。


秘密情報を含まない環境変数は project.*.json に記述する

秘密情報を含まない通常の環境変数は project.*.json に記述してソースコードリポジトリに含めます


project.staging.json

{

"environment": {
"AUTH_ACCOUNT": "1234567890"
}
}


project.production.json

{

"environment": {
"AUTH_ACCOUNT": "abcdefghijk"
}
}


秘密情報を含む環境変数はデプロイ時の引数 --env-file で渡す

パスワードなど、秘密情報を含む環境変数は env.*.json に記述し、--env-file でデプロイ時の引数として指定します。

環境変数を記述した env.*.jsonソースコードリポジトリには含めません

なお、環境変数の優先順位は以下の順番です:


  • -s, --set flag values

  • -E, --env-file file values

  • environment variables specified in project.json or function.json

したがって、project.*.json には環境変数のキー名だけ埋め込んでおき、env.*.jsonで実際の値を注入するのがよいと思います。


project.staging.json

{

"environment": {
"AUTH_ACCOUNT": "1234567890",
"AUTH_SECURITY_TOKEN": ""
}
}


project.production.json

{

"environment": {
"AUTH_ACCOUNT": "abcdefghijk",
"AUTH_SECURITY_TOKEN": ""
}
}


env.staging.json

{

"AUTH_SECURITY_TOKEN": "XXXXXXXXXXXXXXX"
}


env.production.json

{

"AUTH_SECURITY_TOKEN": "YYYYYYYYYYYYYYY"
}


デプロイ

実際にデプロイするときのコマンドは以下のようになります。


staging

apex deploy --env-file=env.staging.json --env=staging


production

apex deploy --env-file=env.production.json --env=production


参考