LambdaProjectを新設したので、デプロイ周りを構築中。
環境変数をパラメータストアから取得しようとしたら・・・
SSM Secure reference is not supported in: [AWS::Lambda::Function/Properties/Environment/Variables/ENV_NAME]
なん....だと?
公式ドキュメントを見ると。
Resources that support dynamic parameter patterns for secure strings
Resources that support the ssm-secure dynamic reference pattern currently include:
- AWS::DirectoryService::MicrosoftAD
- AWS::DirectoryService::SimpleAD
- AWS::ElastiCache::ReplicationGroup
- AWS::IAM::User
- AWS::KinesisFirehose::DeliveryStream
- AWS::OpsWorks::App
- AWS::OpsWorks::Stack
- AWS::OpsWorks::Stack
- AWS::RDS::DBCluster
- AWS::RDS::DBInstance
- AWS::Redshift::Cluster
Lambdaがサポートされていない...!!!
しょうがないので強引にパラメータストアから取得するように挑戦。
成果物
CodePipeLine + CloudFormationの構成を想定。
その他基本設定については割愛する。
template.yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
Lambda:
Type: AWS::Lambda::Function
Properties:
Code: app.zip
FunctionName: LamndaFunction
Handler: index.handler
Runtime: nodejs12.x
Environment:
Variables:
ENV01: __ENV01__
ENV02: __ENV02__
Role:
Fn::GetAtt:
- "Role"
- "Arn"
MemorySize: 1024
Timeout: 3
Role:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "edgelambda.amazonaws.com"
- "lambda.amazonaws.com"
Action:
- sts:AssumeRole
buildspec.yaml
version: 0.2
phases:
install:
runtime-versions:
nodejs: 12
commands:
- yum install -y aws-cli
pre_build:
commands:
- json=$(aws --region ap-northeast-1 ssm get-parameters-by-path --path "/" --with-decryption | jq -r .Parameters)
- len=$(echo $json | jq length)
- for i in $( seq 0 $(($len - 1)) ); do Name=$(echo $json | jq .[$i].Name);Value=$(echo $json | jq .[$i].Value);Key=__$(echo $Name | sed 's/\"//g')__;sed -i -e "s/$Key/$Value/g" ./template.yaml; done
build:
commands:
- yarn install --production=true
- zip -r app.zip index.js node_modules
post_build:
commands:
- aws cloudformation package --template-file template.yaml --s3-bucket BUCKET_NAME --s3-prefix `date '+%Y%m%d%H%M%S'` --output-template-file packaged.yaml
- aws cloudformation deploy --region ap-northeast-1 --template-file packaged.yaml --stack-name STACK_NAME --capabilities CAPABILITY_IAM
artifacts:
files:
- packaged.yaml
説明
簡単に説明すると、CodeBuild内でパラメータストアからキーと値を取ってきて、template.yaml内の文字列を置換しています。
template.yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
Lambda:
Type: AWS::Lambda::Function
Properties:
〜〜〜
Environment:
Variables:
ENV01: __ENV01__
ENV02: __ENV02__
〜〜〜
置換対象の文字列は__${パラメータストアのkey名}__
としております。
buildspec.yaml
version: 0.2
phases:
〜〜〜
pre_build:
commands:
- json=$(aws --region ap-northeast-1 ssm get-parameters-by-path --path "/" --with-decryption | jq -r .Parameters)
- len=$(echo $json | jq length)
- for i in $( seq 0 $(($len - 1)) ); do Name=$(echo $json | jq .[$i].Name);Value=$(echo $json | jq .[$i].Value);Key=__$(echo $Name | sed 's/\"//g')__;sed -i -e "s/$Key/$Value/g" ./template.yaml; done
〜〜〜
まずは、パラメータストアの値をjson形式で取得。
.sh
json=$(aws --region ap-northeast-1 ssm get-parameters-by-path --path "/" --with-decryption | jq -r .Parameters)
その後、jsonレコード分ループし、文字列を置換。
.sh
len=$(echo $json | jq length)
for i in $( seq 0 $(($len - 1)) ); do Name=$(echo $json | jq .[$i].Name);Value=$(echo $json | jq .[$i].Value);
Key=__$(echo $Name | sed 's/\"//g')__;sed -i -e "s/$Key/$Value/g" ./template.yaml;
done
以上。