I've created Cognito User Pool through AWS Console, but I want to automate creation of new Cognito User Pools through CloudFormation. Can I export my current User Pool configuration to CloudFormation template?
Its not possible to export. You would need the below 6 resources to automate the process.
Cognito Authenticated role
Cognito unAuthenticated role
User pool
User Pool Client
Identity Pool
Identity Pool Role attachment
You would need 3 outputs which you might need to use in your code. Below is the code for creating these
AWSTemplateFormatVersion: 2010-09-09
Parameters:
envParameter:
Type: String
Default: dev
AllowedValues: [ dev, test, qa, prod ]
Description: Suffix to be added for names.
Resources:
myApiUserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: !Sub myApiUserPool${envParameter}
myApiUserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: !Sub myApiUserPoolClient${envParameter},
GenerateSecret: False
RefreshTokenValidity: 30
UserPoolId: !Ref myApiUserPool
myApiIdentityPool:
Type: "AWS::Cognito::IdentityPool"
Properties:
IdentityPoolName: !Sub myApiIdentityPool${envParameter}
AllowUnauthenticatedIdentities: False
CognitoIdentityProviders:
- ClientId: !Ref myApiUserPoolClient
ProviderName: !GetAtt myApiUserPool.ProviderName
cognitoUnauthRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub Cognito_${myApiIdentityPool.Name}_Unauth_Role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Federated: cognito-identity.amazonaws.com
Action: [ 'sts:AssumeRole' ]
Policies:
- PolicyName: cognitounauth
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- mobileanalytics:PutEvents
- cognito-sync:*
Resource:
- "*"
cognitoAuthRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub Cognito_${myApiIdentityPool.Name}_Auth_Role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Federated: cognito-identity.amazonaws.com
Action: [ 'sts:AssumeRole' ]
Policies:
- PolicyName: cognitoauth
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- mobileanalytics:PutEvents
- cognito-sync:*
- execute-api:*
Resource:
- "*"
myApiIdentityPoolRoleAttachment:
DependsOn: [ myApiIdentityPool, cognitoUnauthRole, cognitoAuthRole ]
Type: "AWS::Cognito::IdentityPoolRoleAttachment"
Properties:
IdentityPoolId: !Ref myApiIdentityPool
Roles:
authenticated: !GetAtt cognitoAuthRole.Arn
unauthenticated: !GetAtt cognitoUnauthRole.Arn
Outputs:
userPool:
Description: "User pool ID"
Value: !Ref myApiUserPool
identityPool:
Description: "Identity pool ID"
Value: !Ref myApiIdentityPool
ClientId:
Description: "Client id for the user pool appclient"
Value: !Ref myApiUserPoolClient
It's not currently possible to export existing user pools from Cognito. You can, however, create new user pools in AWS CloudFormation and then manage those pools from CloudFormation itself going forward, using AWS::Cognito::UserPool resource type.
I am going to use the describe-user-pool action and then build the cf template based on the output
Related
I'm trying to create a admin API using api gateway, lambda and dynamoDB. I want only the logged in users in certain group be able to access lambda.
I see that the lambda would not assume role of the cognito user and access the dynamoDB. API only works if I attach the dynamoDB policy to the LambdaRole.
Is there a way for this to work dynamically based on user groups. Do I need to add this assumeRole logic in the lambda handler itself ? Please help
This is the ERROR I get when I git my API from postman with Authorization tokens
{
"message": "User: arn:aws:sts::09723XXXXX357:assumed-role/tango-admin-lambda-role/tango-admin-service-dev-getActiveOrders is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:09723XXXXX357:table/dev-tango-service-tango-order-db",
"code": "AccessDeniedException",
"time": "2022-05-23T18:42:39.241Z",
"requestId": "DDK7AS6SBO8D0U3KXXXXXXXX",
"statusCode": 400,
"retryable": false,
"retryDelay": 46.2351059972586
}
Here is my serverless.yml file
service: tango-admin-service
provider:
name: aws
runtime: nodejs14.x
region: us-east-1
environment:
DYNAMODB_TABLE: ${opt:stage, self:provider.stage}-tango-service-tango-order-db
# functions
functions:
hello:
handler: src/handlers/hello.handler
events:
- http:
path: hello
method: get
getActiveOrders:
handler: src/handlers/getActiveOrders.handler
role: TangoAdminLambdaRole # How can this role be assume from Congito ? It only works if I directly pass the Role with DynamoDB Policy
events: # The events that trigger this function
- http:
path: get-active-orders
method: post
cors: true
authorizer:
type: COGNITO_USER_POOLS
authorizerId:
Ref: TangoAdminApiAuthorizer
# Serverless plugins
plugins:
- serverless-plugin-typescript
- serverless-offline
resources:
Resources:
TangoAdminCognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: TangoAdmin
TangoAdminCognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: TangoAdminWebApp
GenerateSecret: false
UserPoolId:
Ref: "TangoAdminCognitoUserPool"
TangoAdminGroup:
Type: AWS::Cognito::UserPoolGroup
Properties:
GroupName: "TangoAdmin"
Description: "Admin group for Tango"
Precedence: 0
RoleArn: !GetAtt CognitoAdminIAMRole.Arn
UserPoolId:
Ref: "TangoAdminCognitoUserPool"
CognitoAdminIAMRole:
Type: AWS::IAM::Role
Properties:
RoleName: "tango-admin-role"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Federated:
- "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Policies:
- PolicyName: "tango-admin-group-policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "dynamodb:*"
Resource:
- "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
TangoAdminApiAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: TangoAdmin
RestApiId:
Ref: ApiGatewayRestApi
Type: COGNITO_USER_POOLS
ProviderARNs:
- Fn::GetAtt: [ TangoAdminCognitoUserPool, Arn ]
IdentitySource: method.request.header.Authorization
TangoAdminLambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: "tango-admin-lambda-role"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action:
- "sts:AssumeRole"
Outputs:
TangoAdminCognitoUserPoolId:
Description: "Tango Admin Cognito User Pool ID"
Value:
Ref: "TangoAdminCognitoUserPool"
TangoAdminCognitoUserPoolClientId:
Description: "Tango Admin Cognito User Pool Client ID"
Value:
Ref: "TangoAdminCognitoUserPoolClient"
I have a serverless application, which creates a KMS Resource:
# serverless.yml 1
resources:
Resources:
SomeLambdaRole:
Type: AWS::IAM::Role
AnotherLambdaRole:
Type: AWS::IAM::Role
TheKey:
Type: AWS::KMS::Key
DeletionPolicy: Retain
Properties:
Description: The key
Enabled: true
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: Allow use of the key
Effect: Allow
Principal:
AWS:
- Fn::GetAtt: [SomeLambdaRole, Arn]
- Fn::GetAtt: [AnotherLambdaRole, Arn]
Action:
- 'kms:Encrypt'
- 'kms:Decrypt'
- 'kms:ReEncrypt'
- 'kms:GenerateDataKey*'
Resource: '*'
From another serverless application where some roles are created, I want to give these new roles the same permissions that SomeLambdaRole and AnotherLambdaRole have on the "TheKey" Resource
# serverless.yml 2
resources:
Resources:
YetAnotherLambdaRole:
Type: AWS::IAM::Role
# Do something to let this role have the same permission as "SomeLambdaRole" and "AnotherLambdaRole" for the "TheKey" Resource
Is this possible or should I try another approach?
for days I have not been able to figure out why one AWS role is not authorized to perform AssumeRole on another. In this case I have a dev-account with AWS CodeCommit on it, and a tools account with CodePipeline. I am trying to allow CodePipeline (in tools) to access CodeCommit (in dev), but am always told that the role in tools is not authorized to do so.
Here is my CloudFormation template to create a role in dev:
AWSTemplateFormatVersion: "2010-09-09"
Description: Cross Account Role to Allow Access to CodePipeline in Tools Account
Parameters:
ToolsAccount:
Description: AWS AccountNumber for tools account
Type: Number
Resources:
Role:
Type: AWS::IAM::Role
Properties:
RoleName: access-codecommit-in-dev
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS:
- !Ref ToolsAccount
Action:
- sts:AssumeRole
Path: /
Policy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub ToolsAcctCodePipelineCodeCommitPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- codecommit:BatchGetRepositories
- codecommit:Get*
- codecommit:GitPull
- codecommit:List*
- codecommit:CancelUploadArchive
- codecommit:UploadArchive
- s3:*
Resource: "*"
Roles:
- !Ref Role
Here is the CloudFormation template that creates CodePipeline:
Description: "Code pipeline to deploy frontend"
Parameters:
DevAccount:
Description: AWS AccountNumber for dev
Type: Number
TestAccount:
Description: AWS AccountNumber for test
Type: Number
Resources:
BuildProjectRole:
Type: AWS::IAM::Role
Properties:
RoleName: codebuild-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- codebuild.amazonaws.com
Action:
- sts:AssumeRole
BuildProjectPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: codebuild-policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:PutObject
- s3:GetBucketPolicy
- s3:GetObject
- s3:ListBucket
Resource:
- "bucketNameHere"
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
Roles:
- !Ref BuildProjectRole
PipeLineRole:
Type: AWS::IAM::Role
Properties:
RoleName: codepipeline-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- codepipeline.amazonaws.com
Action:
- sts:AssumeRole
PipelinePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: codepipeline-policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- codepipeline:*
- iam:ListRoles
- cloudformation:Describe*
- cloudFormation:List*
- codecommit:List*
- codecommit:Get*
- codecommit:GitPull
- codecommit:UploadArchive
- codecommit:CancelUploadArchive
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- cloudformation:CreateStack
- cloudformation:DeleteStack
- cloudformation:DescribeStacks
- cloudformation:UpdateStack
- cloudformation:CreateChangeSet
- cloudformation:DeleteChangeSet
- cloudformation:DescribeChangeSet
- cloudformation:ExecuteChangeSet
- cloudformation:SetStackPolicy
- cloudformation:ValidateTemplate
- iam:PassRole
- s3:ListAllMyBuckets
- s3:GetBucketLocation
Resource:
- "*"
- Effect: Allow
Action:
- s3:PutObject
- s3:GetBucketPolicy
- s3:GetObject
- s3:ListBucket
Resource:
- "bucketName"
- Effect: Allow
Action:
- sts:AssumeRole
Resource:
- !Sub arn:aws:iam::${DevAccount}:role/crossaccount-codecommit-access
Roles:
- !Ref PipeLineRole
FrontEndPipeline:
Type: "AWS::CodePipeline::Pipeline"
Properties:
ArtifactStore:
Type: "S3"
Location: "bucketName"
Name: "frontend-deploy"
RoleArn: !GetAtt PipeLineRole.Arn
Stages:
- Name: "Code-Fetch"
Actions:
- Name: "stage-source"
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeCommit
Version: 1
OutputArtifacts:
- Name: SourceCode
Configuration:
PollForSourceChanges: true
BranchName: develop
RepositoryName: "nameHere"
RunOrder: 1
RoleArn: !Sub arn:aws:iam::${DevAccount}:role/crossaccount-codecommit-access
- Name: Build
Actions:
- Name: "Build-Source"
ActionTypeId:
Category: Build
Owner: AWS
Version: "1"
Provider: CodeBuild
InputArtifacts:
- Name: SourceCode
OutputArtifacts:
- Name: DeployOutput
Configuration:
ProjectName: "CodeBuild"
RunOrder: 1
- Name: Deploy
Actions:
- Name: deploy
ActionTypeId:
Category: Deploy
Owner: AWS
Version: "1"
Provider: S3
InputArtifacts:
- Name: DeployOutput
Configuration:
BucketName: "bucketNameHere"
Extract: true
#RoleArn: !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: "CodeBuild"
ServiceRole: !GetAtt BuildProjectRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Type: LINUX_CONTAINER
Image: node:13
Source:
Type: CODEPIPELINE
What could possibly be generating this error:
arn:aws:iam::{ToolsAccount}:role/projectName-codepipeline-role is not authorized to perform AssumeRole on role arn:aws:iam::{DevAcciybt}:role/access-codecommit-in-dev (Service: AWSCodePipeline; Status Code: 400; Error Code: InvalidStructureException; Request ID: (ID here))
Does the role
arn:aws:iam::{ToolsAccount}:role/projectName-codepipeline-role have permission to assume the role in dev account something like below:
{
"Sid": "AssumeCrossAccountRole"
"Effect": "Allow",
"Actions": "sts:AssumeRole",
"Resource": "ARN of dev account role"
}
else
Try out with passing ARN arn:aws:iam::{ToolsAccount}:role/projectName-codepipeline-role in the AWS principal instead of account number for the role which you are creating in dev account
I am having trouble creating a stack with my CloudFormation template. When it reaches the IdentityPoolRoleAttachment I get the error:
Access to Role 'CognitoIdentityUnauthenticated' is forbidden. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: NotAuthorizedException; Request ID: 0866b3a1-15ab-11e9-82dd-1b30dc4a6a4d)
I've matched everything to what was created through the console and cannot figure out the problem. Can anyone see what I might be missing?
AWSTemplateFormatVersion: 2010-09-09
Description: AWS Script to create Cognito User and Identity pools
Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: cognito-userpool
Schema:
- Name: email
AttributeDataType: String
Mutable: false
Required: true
Policies:
PasswordPolicy:
MinimumLength: 8
RequireLowercase: true
RequireNumbers: true
RequireUppercase: true
CognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: cognito-app-client
ExplicitAuthFlows:
- ADMIN_NO_SRP_AUTH
GenerateSecret: false
ReadAttributes:
- email
RefreshTokenValidity: 30
UserPoolId: !Ref CognitoUserPool
CognitoIdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
IdentityPoolName: cognito_identity_pool
AllowUnauthenticatedIdentities: true
CognitoIdentityProviders:
- ClientId:
Ref: CognitoUserPoolClient
ProviderName:
Fn::GetAtt:
- CognitoUserPool
- ProviderName
CognitoIdentityAuthenticatedRole:
Type: AWS::IAM::Role
Properties:
RoleName: CognitoIdentityAuthenticated
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: CognitoIdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": authenticated
CognitoIdentityUnauthenticatedRole:
Type: AWS::IAM::Role
Properties:
RoleName: CognitoIdentityUnauthenticated
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: CognitoIdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": unauthenticated
# Create policy to allow authenticated user role to invode API lambda function
CognitoAuthInvokeLambdaPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: CognitoAuthInvokeLambdaPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- mobileanalytics:PutEvents
- cognito-sync:*
- cognito-identity:*
Resource:
- "*"
- Effect: Allow
Action:
- execute-api:Invoke
Resource:
- "arn:aws:execute-api:us-east-1:*:xxxxxxxxxx/*"
- Effect: Allow
Action:
- "s3:*"
Resource:
- "*"
Roles:
- Ref: CognitoIdentityAuthenticatedRole
# Create policy to allow unauthenticated user role (currently only has access to Cognito - add additional resources if needed)
CognitoUnauthPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: CognitoUnauthPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- mobileanalytics:PutEvents
- cognito-sync:*
- cognito-identity:*
Resource:
- "*"
Roles:
- Ref: CognitoIdentityUnauthenticatedRole
# Assigns the role to the Identity Pool
CognitoIdentityPoolRoleMapping:
Type: "AWS::Cognito::IdentityPoolRoleAttachment"
Properties:
IdentityPoolId: !Ref CognitoIdentityPool
Roles:
authenticated: !Ref CognitoIdentityAuthenticatedRole
unauthenticated: !Ref CognitoIdentityUnauthenticatedRole
#Output IDs and ARNs
Outputs:
CognitoUserPoolID:
Value:
Ref: CognitoUserPool
Export:
Name: !Sub "${AWS::StackName}-CognitoUserPoolID"
CognitoUserPoolClientID:
Value:
Ref: CognitoUserPoolClient
Export:
Name: !Sub "${AWS::StackName}-CognitoUserPoolClientID"
CognitoIdentityPoolID:
Value:
Ref: CognitoIdentityPool
Export:
Name: !Sub "${AWS::StackName}-CognitoIdentityPoolID"
I see a similar question posted but no answer was provided: Access to Role 'cognito role' is forbidden
I figured it out. The unauthenticated role needs the Arn and not the logical ID.
CognitoIdentityPoolRoleMapping:
Type: "AWS::Cognito::IdentityPoolRoleAttachment"
Properties:
IdentityPoolId: !Ref CognitoIdentityPool
Roles:
authenticated: !GetAtt CognitoIdentityAuthenticatedRole.Arn
unauthenticated: !GetAtt CognitoIdentityUnauthenticatedRole.Arn
I'm getting this strange error
Access to Role 'cognito role' is forbidden.
while creating a cloud formation stack here is my cloud formation file in yaml format.
I'm basically creating a s3 bucket and a cognito identity to facilate client side access to my bucket the whole thing is working fine except this error
Access to Role 'phototest-cognitoRole-1AMKUVXUXAJ5H' is forbidden. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: NotAuthorizedException
AWSTemplateFormatVersion: 2010-09-09
Resources:
photoBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: it-academy-photos-bucket
CorsConfiguration:
CorsRules:
- AllowedHeaders: ['*']
AllowedMethods: [GET,POST,PUT]
AllowedOrigins: ['*']
Id: myrules
cognitoRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Principal:
Federated:
- "cognito-identity.amazonaws.com"
Action:
- sts:AssumeRoleWithWebIdentity
Policies:
-
PolicyName: "photo_client_policy"
PolicyDocument:
Version: '2012-10-17'
Statement:
-
Sid: VisualEditor1
Effect: Allow
Action:
- s3:PutObject
- s3:GetObjectAcl
- s3:GetObject
- s3:GetObjectTorrent
- s3:GetObjectVersionAcl
- s3:PutObjectVersionTagging
- s3:GetObjectTagging
- s3:PutObjectTagging
- s3:PutBucketCORS
- s3:PutObjectAcl
- s3:GetObjectVersion
Resource: "*"
cognitoIdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
IdentityPoolName: "photo_bucket"
AllowUnauthenticatedIdentities: true
cognitoIdentityPoolRoleAttachment:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId: !Ref cognitoIdentityPool
Roles:
unauthenticated: !Ref cognitoRole
I was having the same problem and figured out the unauthenticated role needs the Arn and not the logical ID. This should fix the issue:
cognitoIdentityPoolRoleAttachment:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId: !Ref cognitoIdentityPool
Roles:
unauthenticated: !GetAtt cognitoRole.Arn