@altcatalin Thanks for the idea, but it still barfs on it on a new line.
@pgali The environment variable can be read in the function no problem, but I’m trying to get the framework to set up the authorizer for me automatically. That may be asking to much, I’m beginning to think 8).
have you also tried with the long function form?
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html
this works
functions:
ConsumerFunction:
...
environment:
QUEUE_ARN:
Fn::GetAtt:
- Queue
- Arn
resources: # CloudFormation template syntax
Resources:
# SQS
Queue:
Type: AWS::SQS::Queue
...
FYI, just got confirmation that this is a bug that will be fixed as part of a larger ARN issue, workaround described here:
opened 12:57PM - 08 Feb 17 UTC
This is a Feature proposal
Description
Note: This issue was updated from a bug report to a feature proposal. The implementation of the...
feature
help wanted
Basically, create your stack once, come back to your serverless.yml and hard code the ARN that gets generated.
I found this gist on github which helped solve a lot of my problems: https://gist.github.com/singledigit/2c4d7232fa96d9e98a3de89cf6ebe7a5
I’ve gotten this to work with text message verification using gist from @barticus … but how it works with email verification I am not sure.
iDVB
November 9, 2017, 9:07pm
12
Has anyone found out more about this. I’m looking to do the exact same thing you @nerdguru .
Can’t see to get the authorizer to take in a GetAtt call to the resource. I keep getting the SLS error
functionArn.split is not a function
dan_b
December 23, 2017, 12:10am
13
I was able to get serverless to generate my identity pool using the following:
IdentityPool:
Type: "AWS::Cognito::IdentityPool"
Properties:
IdentityPoolName: identitypoolname
AllowUnauthenticatedIdentities: true
CognitoIdentityProviders:
- ClientId:
Ref: UserPoolClient
ProviderName:
'Fn::GetAtt': [ MyUserPool, ProviderName ]
Hope this helps
This will setup userpools that are compatible with aws-amplify
service:
name: digiStatic
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs6.10
memorySize: 512
# Serverless variables like ${self:custom.prefix} We use variableSyntax here
# to change serverless vars to look instead like $<self:custom.prefix>
variableSyntax: '\$<([ :a-zA-Z0-9._,\\-\\/\\(\\)]+?)>'
plugins:
- serverless-stack-output
custom:
output:
handler: scripts/output.handler # Same syntax as you already know
file: ../stack.json # toml, yaml, yml, and json format is available
resources:
Resources:
# Creates a user pool in cognito for your app to auth against
# Fixme: customer email address needs to be manually entered and verified
# https://console.aws.amazon.com/ses/home?region=us-east-1#verified-senders-email:
# Time based MFA can not be enabled from script
# I have asked AWS to fix this
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: $<self:service>-user-pool
SmsVerificationMessage: "Your verification code is {####}."
AutoVerifiedAttributes:
- email
MfaConfiguration: "OFF"
EmailVerificationSubject: "Your Digispeaker verification code"
EmailVerificationMessage: "Your Digispeaker verification code is {####}."
SmsAuthenticationMessage: "Your Digispeaker authentication code is {####}."
Schema:
- Name: name
AttributeDataType: String
Mutable: true
Required: false
- Name: email
AttributeDataType: String
Mutable: false
Required: true
- Name: phone_number
AttributeDataType: String
Mutable: true
Required: false
Policies:
PasswordPolicy:
RequireLowercase: true
RequireSymbols: false
RequireNumbers: true
MinimumLength: 8
RequireUppercase: true
AdminCreateUserConfig:
InviteMessageTemplate:
EmailMessage: "Your Digispeaker username is {username} and temporary password is {####}."
EmailSubject: "Your temporary Digispeaker password"
SMSMessage: "Your Digispeaker username is {username} and temporary password is {####}."
UnusedAccountValidityDays: 7
AllowAdminCreateUserOnly: false
# Creates a User Pool Client to be used by the identity pool
UserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: $<self:service>-client
GenerateSecret: false
UserPoolId:
Ref: UserPool
# Creates a federeated Identity pool
IdentityPool:
Type: "AWS::Cognito::IdentityPool"
Properties:
IdentityPoolName: $<self:service>Identity
AllowUnauthenticatedIdentities: true
CognitoIdentityProviders:
- ClientId:
Ref: UserPoolClient
ProviderName:
'Fn::GetAtt': [ UserPool, ProviderName ]
SupportedLoginProviders:
'graph.facebook.com': "xxxxxxxxxx"
OpenIdConnectProviderARNs:
- 'arn:aws:iam::xxxxxxxxxxx:oidc-provider/accounts.google.com'
# Create a role for unauthorized acces to AWS resources. Very limited access. Only allows users in the previously created Identity Pool
CognitoUnAuthorizedRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Federated: "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud":
Ref: IdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": unauthenticated
Policies:
- PolicyName: "CognitoUnauthorizedPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "mobileanalytics:PutEvents"
- "cognito-sync:*"
Resource: "*"
# Create a role for authorized acces to AWS resources. Control what your user can access. This example only allows Lambda invokation
# Only allows users in the previously created Identity Pool
CognitoAuthorizedRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Federated: "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud":
Ref: IdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": authenticated
Policies:
- PolicyName: "CognitoAuthorizedPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "mobileanalytics:PutEvents"
- "cognito-sync:*"
- "cognito-identity:*"
Resource: "*"
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: "*"
# Assigns the roles to the Identity Pool
IdentityPoolRoleMapping:
Type: "AWS::Cognito::IdentityPoolRoleAttachment"
Properties:
IdentityPoolId:
Ref: IdentityPool
Roles:
authenticated:
'Fn::GetAtt': [ CognitoAuthorizedRole, Arn ]
unauthenticated:
'Fn::GetAtt': [ CognitoUnAuthorizedRole, Arn ]
Outputs:
UserPoolId:
Value:
Ref: UserPool
Export:
Name: "UserPool::Id"
UserPoolClientId:
Value:
Ref: UserPoolClient
Export:
Name: "UserPoolClient::Id"
IdentityPoolId:
Value:
Ref: IdentityPool
Export:
Name: "IdentityPool::Id"
9 Likes
Thanks @jonsmirl - your example has been extremely helpful to me. Any chance you could tell me what I’d need to change to configure the User Pool resource so that it is set up to use the user’s email address as their “username”. I can do this via the AWS console but I want to put this config in serverless.yml.
I think you remove the ‘name’ field. But does amplify support that yet? I don’t think they have gotten around to making the userpool stuff configurable yet.
I don’t really know much about amplify. I just want to add the config for my user pool to my serverless service and I was able to take what I needed from your example and use that to create a user pool successfully, just not with the exact config I need.
The ‘name’ field is different to ‘username’ so I don’t think removing that will achieve what I want. Are you able to point me in direction of any docs/tutorials that might help me out? Thanks again!
Use the UI to get it the way you like it. Then use the CLI to describe it.
aws cognito-idp describe-user-pool --user-pool-id xxxxxxx
4 Likes
Ah ha! Didn’t know I could do that. Thanks, that’s super helpful.
supun
April 11, 2018, 6:27am
20
hi all
so i want use cognito pool id use in lambda function.
i try to import UserPool::Id to env varible and then use env varible inside lambda. but its not work
got a error :circuiler dependency error within serverless deploy
Is there any update on the issue? I still want to reference the user pool using the ARN dynamically.
prd
September 13, 2018, 1:26pm
22
Something that caught me out on this – Cognito Identity Pools cannot have hyphens in the pool name (unlike user pools and many other named elements).
I was getting a regex error when trying to deploy:
1 validation error detected: Value 'XXXXX; at ‘identityPoolName’ failed to satisfy constraint: Member must satisfy regular expression pattern: [\w ]+ (Service: AmazonCognitoIdentity; Status Code: 400;
Removed the hyphens from the name and it deployed without issue:
‘’’
CognitoIdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
IdentityPoolName: ${self:custom.stage}SomeNameIdentityPool
AllowUnauthenticatedIdentities: false
CognitoIdentityProviders:
- ClientId:
Ref: CognitoUserPoolClient
ProviderName:
‘Fn::GetAtt’: [“CognitoUserPool”,“ProviderName”]
‘’’
1 Like
Have a look here, may help you, unless you provide a string to arn
, the resource build in serverless assumes you’re trying to reference a lambda function to make the authorization, and can only build that kind of authorizer for you: https://github.com/serverless/serverless/blob/master/lib/plugins/aws/package/compile/events/apiGateway/lib/authorizers.js#L27
I managed to dynamically build an Authorizer reference like this:
1 Like
Thanks, you’re a lifesaver
1 Like
mrowles
February 3, 2019, 8:57pm
27
This is great, thanks @jonsmirl !
It looks like this might not facilitate multiple environments, however, as the error I’m getting seems to be from the ‘Outputs’:
service-prod - Export with name UserPoolClient::Id is already exported by stack service-pre.
The only alternative I can think of doing, since we cannot use strings as key/property names in YAML, perhaps exporting both versions of pre/prod:
Outputs:
UserPoolIdpre:
Value:
Ref: UserPoolpre
Export:
Name: 'UserPool::Id'
UserPoolIdprod:
Value:
Ref: UserPoolprod
Export:
Name: 'UserPool::Id'
UserPoolClient:
Type: 'AWS::Cognito::UserPoolClient'
Properties:
ClientName: service-${self:provider.stage}-web-client
GenerateSecret: false
UserPoolId:
Ref: "UserPool${self:provider.stage}"
Has anyone else figured this one out because this is not scalable, looks ugly and probably doesn’t even work?