【ServerlessFramework】serverless.ymlで利用できる変数のまとめ

serverless.ymlの変数の仕様がどこにまとまっているかわからず、かなり探し回ったのでまとめておこうと思いました。
内容的には公式ドキュメントからよく使いそうなものを抜粋しただけです。

https://www.serverless.com/framework/docs/providers/aws/guide/variables


# 基本的な変数の利用方法
まずはじめに、変数の参照には `${}` を利用します。
```serverless.yml
yamlKeyXYZ: ${variableSource}
```

ちなみに、serverlessの変数は再帰的な参照がサポートされており、変数をネストすることができます。

```provider
provider:
  name: aws
  environment:
    MY_SECRET: ${file(./config.${opt:stage, 'dev'}.json):CREDS}
```

# デフォルト値
参照先の変数が存在しない場合にデフォルト値を利用したい場合は `${variableSource, defaultValue}` を利用します。

```serverless.yml
custom:
  myStage: ${opt:stage, self:provider.stage}
  myRegion: ${opt:region, 'us-west-1'}
```

# serverless.yml内のプロパティの参照
serverless.yml内で定義したプロパティを別のプロパティで参照したい場合は `${self:someProperty}` を利用します。
例えば、 `custom.globalSchedule` を参照したい場合は `${self:custom.globalSchedule}` と記述します。

```serverless.yml
service: new-service
provider: aws
custom:
  globalSchedule: rate(10 minutes)
functions:
  hello:
    handler: handler.hello
    events:
      - schedule: ${self:custom.globalSchedule}
  world:
    handler: handler.world
    events:
      - schedule: ${self:custom.globalSchedule}

```

# serverless内部の変数の参照
ServerlessFramework内部で利用する変数をserverless.ymlから参照する場合は `${sls:XXX}` を利用します。

下記2つが利用可能です。

1. `${sls:instanceId}` : CLI実行ごとのランダムな変数
1. `${sls:stage}` : `${opt:stage, self:provider.stage, "dev"}` のショートカット

# 環境変数の参照
環境変数の参照は `${env:SOME_VAR}` を利用します。

```serverless.yml
service: new-service
provider: aws
functions:
  hello:
    name: ${env:FUNC_PREFIX}-hello
    handler: handler.hello
  world:
    name: ${env:FUNC_PREFIX}-world
    handler: handler.world
```

# CLIパラメータの参照
`sls deploy --param="domain=myapp.com" --param="key=value"` のように指定した[パラメータ](https://www.serverless.com/framework/docs/guides/parameters)の参照は `${param:XXX}` を利用します。

```serverless.yml
provider:
  environment:
    APP_DOMAIN: ${param:domain}
```

# CLIオプションの参照
CLI実行時にオプションとして指定した値の参照は `${opt:<option>}` を利用します。
例えば `sls deploy --stage stg` の `--stage` の値は `${opt:stage}` で参照します。
※ すべてのオプションを参照したい場合は `${opt:}` を利用します。

```serverless.yml
service: new-service
provider: aws
functions:
  hello:
    name: ${opt:stage}-hello
    handler: handler.hello
  world:
    name: ${opt:stage}-world
    handler: handler.world
```

# CloudFormationのOutputsの参照
CloudFormationスタックのOutputs値の参照は `${cf:stackName.outputKey}` を利用します。
※ リージョンを明示的に指定したい場合は `${cf(REGION):stackName.outputKey}` とします。

```serverless.yml
service: new-service
provider: aws
functions:
  hello:
    name: ${cf:another-service-dev.functionPrefix}-hello
    handler: handler.hello
  world:
    name: ${cf(us-west-2):another-stack.functionPrefix}-world
    handler: handler.world
```

# SSMパラメータストアの参照
SSMパラメータストアの値の参照は `${ssm:/path/to/param}` を利用します。
※ リージョンを明示的に指定したい場合は `${ssm(REGION):/path/to/param}` とします。

```serverless.yml
service: ${ssm:/path/to/service/id}-service
provider:
  name: aws
functions:
  hello:
    name: ${ssm:/path/to/service/myParam}-hello
    handler: handler.hello
```

# AWSの固有値の参照
AWSの固有値の参照は `${aws:XXX}` を利用します。

1. `${aws:accountId}` : AWSアカウントID
1. `${aws:region}` : `${opt:region, self:provider.region, "us-east-1"}` のショートカット

```serverless.yml
service: new-service
provider:
  name: aws
functions:
  func1:
    name: function-1
    handler: handler.func1
    environment:
      ACCOUNT_ID: ${aws:accountId}
```

# SecretsManagerの参照
secretsManagerの参照は `${ssm:/aws/reference/secretsmanager/secret_ID_in_Secrets_Manager}` のようにssmを利用します。
例えばSecretsManagerのIDが `secrets/rds/dev` なら `${ssm:/aws/reference/secretsmanager/secrets/rds/dev}` となります。

```serverless.yml
service: new-service
provider: aws
custom:
  rdsSecret: ${ssm:/aws/reference/secretsmanager/secrets/rds/dev}
```

```json:secrets/rds/devのシークレット値
{
  "password": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
  "dbname": "sample",
  "engine": "mysql",
  "port": 3306,
  "dbInstanceIdentifier": "dev01",
  "host": "transapp-rds-mi1.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com",
  "username": "admin"
}
```

この設定だと下記のように展開されます
```bash
sls print
```

```serverless.yml
service: new-service
provider: aws
custom:
  rdsSecrets:
    password: xxxxxxxxxxxxxxxxxxxxxxxxxx
    dbname: sample
    engine: mysql
    port: 3306
    dbInstanceIdentifier: dev01
    host: transapp-rds-mi1.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
    username: admin
```

## シークレット値を文字列として取り出したい場合
デフォルトだとシークレット値は自動で配列・辞書形式にキャストされてしまいますが、文字列として展開したい場合は `${ssm(raw):/aws/reference/secretsmanager/secret_ID_in_Secrets_Manager}` を利用します。
※ リージョンを同時に指定したい場合は `${smm(ap-northeast-1, raw):...}` とします。

```serverless.yml
service: new-service
provider: aws
custom:
  rdsSecret: ${ssm(raw):/aws/reference/secretsmanager/secrets/rds/dev}
```

この設定だと下記のように展開されます
```bash
sls print
```

```serverless.yml
service: new-service
provider: aws
custom:
  rdsSecrets: >-
    {"password":"xxxxxxxxxxxxxxxxxxxxxxxxxx","dbname":"sample","engine":"mysql","port":3306,"dbInstanceIdentifier":"dev01","host":"transapp-rds-mi1.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com","username":"admin"}
```

# 外部ファイルの参照
他のyml, jsonファイルの参照は `${file(./myFile.yml):someProperty}` を利用します。

```customConfig.yml
myevents:
  - schedule:
      rate: rate(1 minute)
```

```serverless.yml
functions:
  hello:
    handler: handler.hello
    events: ${file(./customConfig.yml):myevents}

```
この設定だと下記のように展開されます

```bash
sls print
```

```serverless.yml
functions:
  hello:
    handler: handler.hello
    events:
      - schedule:
          rate: rate(1 minute)
```


# String から Booleanへのキャスト
文字列を真偽値にキャストしたい場合は `${strToBool(variable)}` を利用します。

```serverless.yml
provider:
  tracing:
    apiGateway: ${strToBool(${ssm:API_GW_DEBUG_ENABLED})}
```

変換ルール

```
	
${strToBool(true)} => true
${strToBool(false)} => false
${strToBool(True)} => true
${strToBool(False)} => false
${strToBool(TRUE)} => true
${strToBool(FALSE)} => false
${strToBool(0)} => false
${strToBool(1)} => true
${strToBool(2)} => Error
${strToBool(null)} => Error
${strToBool(anything)} => Error
```