これまで
Amazon Cognito は AWS CloudFormation でのリソース作成と管理に対応しておらず、リソース作成を自動化したい場合は AWS CLI や AWS SDK を使った自作スクリプトを使う必要がありました。
しかし、この方法で冪等性を担保するのは難しく、 CloudFormation Custom Resource を作った猛者もいました。
また、 IAM Role の Assume Policy に Identity Pool の ID を含めないといけない点が特に面倒でした。
これから
2017年4月28日、 Cognito の各種リソースが CloudFormation で作成・管理できるようになりました。
- Amazon Cognito Now Supported by AWS CloudFormation
- AWS::Cognito::IdentityPool - AWS CloudFormation
- AWS::Cognito::IdentityPoolRoleAttachment - AWS CloudFormation
- AWS::Cognito::UserPool - AWS CloudFormation
- AWS::Cognito::UserPoolClient - AWS CloudFormation
- AWS::Cognito::UserPoolGroup - AWS CloudFormation
- AWS::Cognito::UserPoolUser - AWS CloudFormation
- AWS::Cognito::UserPoolUserToGroupAttachment - AWS CloudFormation
これが待ち望んでいたものです。
User Pool 内のユーザーやグループまでリソースとして用意されているのが面白いですね。
IAM Role も同じスタック内で作ってしまえば Assume Policy の中で Identity Pool の ID も参照できるので、手動で ID をコピペする手間が省けて最高です。
テンプレート例
AWSTemplateFormatVersion: "2010-09-09"
Description: "Example template including Cognito Identity Pool and User Pool."
Parameters:
EmailIdentityArn:
Type: String
Resources:
UserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName:
Fn::Join:
- ""
- - Ref: AWS::StackName
- Users
AdminCreateUserConfig:
AllowAdminCreateUserOnly: false
AliasAttributes:
- email
- preferred_username
AutoVerifiedAttributes:
- email
EmailConfiguration:
SourceArn:
Ref: EmailIdentityArn
Policies:
PasswordPolicy:
MinimumLength: 8
RequireLowercase: true
RequireNumbers: true
RequireSymbols: false
RequireUppercase: true
Schema:
- Name: email
AttributeDataType: String
DeveloperOnlyAttribute: false
Mutable: true
Required: true
- Name: preferred_username
AttributeDataType: String
DeveloperOnlyAttribute: false
Mutable: true
Required: false
UserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName:
Fn::Join:
- ""
- - Ref: AWS::StackName
- Users-client
GenerateSecret: false
RefreshTokenValidity: 7
UserPoolId:
Ref: UserPool
IdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
AllowUnauthenticatedIdentities: true
IdentityPoolName:
Fn::Join:
- ""
- - Ref: AWS::StackName
- Users
CognitoIdentityProviders:
- ClientId:
Ref: UserPoolClient
ProviderName:
Fn::Join:
- ""
- - cognito-idp.
- Ref: "AWS::Region"
- .amazonaws.com/
- Ref: UserPool
UnauthenticatedPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- mobileanalytics:PutEvents
- cognito-sync:*
Resource:
- "*"
UnauthenticatedRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "sts:AssumeRoleWithWebIdentity"
Principal:
Federated: cognito-identity.amazonaws.com
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud":
Ref: IdentityPool
ForAnyValue:StringLike:
"cognito-identity.amazonaws.com:amr": unauthenticated
ManagedPolicyArns:
- Ref: UnauthenticatedPolicy
AuthenticatedPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- mobileanalytics:PutEvents
- cognito-sync:*
- cognito-identity:*
Resource:
- "*"
AuthenticatedRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "sts:AssumeRoleWithWebIdentity"
Principal:
Federated: cognito-identity.amazonaws.com
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud":
Ref: IdentityPool
ForAnyValue:StringLike:
"cognito-identity.amazonaws.com:amr": authenticated
ManagedPolicyArns:
- Ref: AuthenticatedPolicy
RoleAttachment:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId:
Ref: IdentityPool
Roles:
unauthenticated:
Fn::GetAtt:
- UnauthenticatedRole
- Arn
authenticated:
Fn::GetAtt:
- AuthenticatedRole
- Arn
Outputs:
UserPool:
Value:
Ref: UserPool
UserPoolClient:
Value:
Ref: UserPoolClient
IdentityPool:
Value:
Ref: IdentityPool
UnauthenticatedRole:
Value:
Ref: UnauthenticatedRole
AuthenticatedRole:
Value:
Ref: AuthenticatedRole
その他の活用方法
Serverless Framework は CloudFormation のリソーステンプレートを埋め込めるので、 User Pool のトリガーで使う Lambda ファンクションを同時作成するのにうってつけです。
その場合は AWS::Cognito::UserPool の LambdaConfig プロパティ を指定してトリガーを設定します。また、 AWS::Lambda::Permission も忘れずに作る必要があります(Principal
は cognito-idp.amazonaws.com
)。