やりたかったこと
- serverless.ymlの
provider.environment
にはローカル環境とデプロイする環境で別の値を入れたい- デプロイする環境では同yaml内で作成したリソースのID等を
Ref:
して定義したい-
resources
はcloudformationなのでRef:
等が使えるのは知ってる -
provider.environment
とかでもRef:
したいんだけどできるのかな?
-
- ローカル環境ではコンテナの環境変数を参照して定義したい
- ローカルは serverless-offline on docker な環境
- そこではリソースの作成は行われないので、コンテナの環境変数を読む必要があった
- デプロイする環境では同yaml内で作成したリソースのID等を
結果
-
Ref:
できた-
custom
にて、作成したリソースの情報を取得している - 全てを試してはいないが、同yaml内であればどこでも使えそうな感じ
- ただし、
!Ref
といった記述はできないっぽい
-
- 環境変数を読む / Ref:するに関して
- ステージごとに
provider.environment
を制御することで実現できた - デプロイ時には
Ref:
の値を利用し、コンテナのserverless-offlineでは環境変数を読み込む
- ステージごとに
serverless.yml
ちょこちょこ情報は削ってますが、こんな感じのyamlになります
cognitoのリソースを作成している
serverless.yml
provider:
name: aws
runtime: nodejs8.10
region: ${env:AWS_REGION}
stage: ${opt:stage, self:custom.defaultStage}
environment:
COGNITO_DOMAIN: ${env:COGNITO_DOMAIN}
COGNITO_CLIENT_ID: ${self:custom.cognito.clientId.${self:provider.stage}}
COGNITO_USER_POOL_ID: ${self:custom.cognito.userPoolId.${self:provider.stage}}
vpc:
securityGroupIds:
- ${env:SECURITY_GROUP_ID}
subnetIds:
- ${env:SUBNET_ID_0}
- ${env:SUBNET_ID_1}
iamRoleStatements:
- Effect: "Allow"
Action:
- "ec2:CreateNetworkInterface"
- "ec2:DescribeNetworkInterfaces"
- "ec2:DeleteNetworkInterface"
- "cognito-idp:*"
Resource:
- "*"
custom:
defaultStage: dev
cognito:
clientId:
dev:
Ref: UserPoolClient
local: ${env:COGNITO_CLIENT_ID}
userPoolId:
dev:
Ref: UserPool
local: ${env:COGNITO_USER_POOL_ID}
functions:
# 〜略〜
resources:
Resources:
UserPool:
Type: AWS::Cognito::UserPool
Properties:
# 〜略〜
UserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
# 〜略〜
UserPoolId:
Ref: UserPool
解説
コンテナで叩くコマンド
$ serverless offline --stage local
serverless.ymlの状態
COGNITO_CLIENT_ID: ${env:COGNITO_CLIENT_ID}
COGNITO_USER_POOL_ID: ${COGNITO_USER_POOL_ID}
デプロイする時のコマンド
$ serverless deploy
serverless.ymlの状態
COGNITO_CLIENT_ID:
Ref: UserPoolClient
COGNITO_USER_POOL_ID:
Ref: UserPool
-
opt:stage
- コマンドラインオプションの
--stage
で指定した値
- コマンドラインオプションの
-
self:custom.defaultStage
- コマンドラインオプション
--stage
の指定がなかった場合、custom.defaultStage
がデフォルト値となる
- コマンドラインオプション
-
\${self:custom.cognito.clientId.${self:provider.stage}}
- ${self:provider.stage} =
dev
または--stageの引数
- つまり今回の場合、
custom.cognito.clientId.dev
またはcustom.cognito.clientId.local
- ${self:provider.stage} =
ちなみに
-
self
- このserverless.yml自身を指す
-
custom
- 独自定義した値
docker-compose.yml
docker-compose.yml
version: '3'
services:
slsdb:
image: mariadb:10.2
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --skip-character-set-client-handshake
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD
- MYSQL_DATABASE
slsapp:
build: .
command: npx serverless offline --stage local --host 0.0.0.0 --port 3000
volumes:
- .:/application
- /application/node_modules
ports:
- "3000:3000"
depends_on:
- slsdb
environment:
- SECURITY_GROUP_ID
- SUBNET_ID_0
- SUBNET_ID_1
- MYSQL_ROOT_PASSWORD
- MYSQL_DATABASE
- MYSQL_USER
- MYSQL_HOST
- MYSQL_PORT
- COGNITO_CLIENT_ID
- COGNITO_USER_POOL_ID
- COGNITO_DOMAIN
解説
コンテナを立ち上げ時、コマンド npx serverless offline --stage local --host 0.0.0.0 --port 3000
を実行する
--stage local
オプションを指定しているため、serverless.ymlで記載した通り、serverless.ymlではlocal
の値を使用してserverless-offlineが起動する
また、AWSリソースの作成は行われないため、一度デプロイしたあと、COGNITO_CLIENT_ID
等の値をコンテナの環境変数に設定しないといけないところは注意。