production.log

株式会社リブセンスでエンジニアをやっている星直史のブログです。

Serverless Framework 1.10.2でAWS IAM変数(${cognito-identity.amazonaws.com:sub})を使用する場合の設定

概要

標題の通りですが、Serverless Framework 1.10.2において、serverless.ymlにAWS IAM変数(${cognito-identity.amazonaws.com:sub}など)を使用する場合、
フレームワークの挙動として${文字列}の値を設定した変数に置き換えようとする動きをするので、その挙動を変更し、IAM変数を使えるようにする方法を書きます。
※今回はcognito-identity.amazonaws.com:subに限定して書きますので、汎用的ではありません。

元のコード

provider:
  name: aws 
  runtime: nodejs6.10
  stage: dev 
  region: us-west-2
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:PutObject"
      Resource: "arn:aws:s3:::mybucket/${self:provider.stage}/${cognito-identity.amazonaws.com:sub}/*"

このような感じで、自分のcognito identityに紐づいたs3 bucketしか触らせないようにするIAM Roleを記述し、 sls deploy -vした場合、

  Serverless Error ---------------------------------------
 
     Invalid variable reference syntax for variable cognito-identity.amazonaws.com.
     You can only reference env vars, options, & files. You
     can check our docs for more info.

こんな感じで怒られます。 そんな変数ねーよって感じですね。

そこで、ここの処理をどうしているのか追っていったところ
variableSyntaxという名の、それっぽものがありました。

さらに調べると、providerブロックの直下にvariableSyntaxを記述すると、記述した値でオーバーライドされとのことでした。 正直正規表現で全てのパターンを網羅するの気合いがなかったので、cognitoに限定した正規表現を作りました。

修正前: variableSyntax: '\\${([ :a-zA-Z0-9._,\\-\\/\\(\\)]+?)}'
修正後: variableSyntax: "\\${([^cognito*+][ :a-zA-Z0-9._,\\-\\/\\(\\)]+?)}"

単純ですね。cognito*+だった場合は対象から除外しているだけです。

修正後のコード

provider:
  name: aws 
  variableSyntax: "\\${([^cognito*+][ :a-zA-Z0-9._,\\-\\/\\(\\)]+?)}"
  runtime: nodejs6.10
  stage: dev 
  region: us-west-2
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:PutObject"
      Resource: "arn:aws:s3:::mybucket/${self:provider.stage}/${cognito-identity.amazonaws.com:sub}/*"

これで、deployし、AWS マネジメントコンソールのIAM > Roles > Review Policyで確認しましょう。

f:id:watasihasitujidesu:20170412113554p:plain

意図した通りの挙動になっていますね。