Getting Cloudformation error: Embedded stack was not successfully created - amazon-web-services

I've made a parent (nested) stack template that references 4 child templates. When I launch the stack through aws cloudformation create-stack, I get the following error for the parent stack:
Embedded stack AlignmentLambdaFunction was not successfully created: The following resource(s) failed to create: [CloudspanLambdaFunction, HaploLambdaExecutionRole, AlignmentLambdaExecutionRole].
And I get this error within one of the nested stacks that was getting created from the parent: Policy contains a statement with one or more invalid principals (for MasterGCPStorageKey (which is a resource in the Lambda child above)
I don't understand the source of the error. I thought maybe it was because of needing a DependsOn for the ExecutionRoles, but that didn't resolve the error.
Parent Stack:
AWSTemplateFormatVersion: "2010-09-09"
Description: "Master template for wgs-pipeline. Calls to other stack templates."
Parameters:
CloudspanLambdaFuncS3BucketName:
Type: String
CloudspanLambdaFuncS3KeyName:
Default: 'sfn.deployable.zip'
Type: String
CloudspanLambdaFuncModuleName:
Default: 'cloudspan'
Type: String
AlignmentLambdaFuncS3BucketName:
Type: String
AlignmentLambdaFuncS3KeyName:
Type: String
AlignmentLambdaFuncModuleName:
Type: String
HaploLambdaFuncS3BucketName:
Type: String
HaploLambdaFuncS3KeyName:
Type: String
HaploLambdaFuncModuleName:
Type: String
KMSAdminUserARN:
Type: String
KMSEndUserARN:
Type: String
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
InternetGateway:
Type: AWS::EC2::InternetGateway
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: 'VPC'
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: 'VPC'
InternetGatewayId:
Ref: 'InternetGateway'
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: EC2 Security Group for instances launched in the VPC by Batch
VpcId:
Ref: 'VPC'
StepFunctionsActivitiesInstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow http to client host
VpcId:
Ref: VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 128.218.0.0/16
Subnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: 10.0.0.0/24
VpcId:
Ref: 'VPC'
AvailabilityZone:
Ref: GPCESubnetAZ1
MapPublicIpOnLaunch: 'True'
DependsOn: VPC
Route:
Type: AWS::EC2::Route
Properties:
RouteTableId:
Ref: 'RouteTable'
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: 'InternetGateway'
DependsOn:
- RouteTable
- InternetGateway
SubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: 'RouteTable'
SubnetId:
Ref: 'Subnet'
DependsOn:
- RouteTable
- Subnet
# Beginning of reference to child stacks
ClouspanLambdaFunction:
Type: "AWS::CloudFormation::Stack"
Properties:
Parameters:
CloudspanLambdaFuncS3BucketName:
Ref: CloudspanLambdaFuncS3BucketName
CloudspanLambdaFuncS3KeyName:
Ref: CloudspanLambdaFuncS3KeyName
CloudspanLambdaFuncModuleName:
Ref: CloudspanLambdaFuncModuleName
KMSAdminUserARN:
Ref: KMSAdminUserARN
KMSEndUserARN:
Ref: KMSEndUserARN
TemplateURL: https://s3.amazonaws.com/CFNTemplate/lambda_resources.stack.yaml
TimeoutInMinutes: 1
AlignmentLambdaFunction:
Type: "AWS::CloudFormation::Stack"
Properties:
Parameters:
AlignmentLambdaFuncS3BucketName:
Ref: AlignmentLambdaFuncS3BucketName
AlignmentLambdaFuncS3KeyName:
Ref: AlignmentLambdaFuncS3KeyName
AlignmentLambdaFuncModuleName:
Ref: AlignmentLambdaFuncModuleName
KMSAdminUserARN:
Ref: KMSAdminUserARN
KMSEndUserARN:
Ref: KMSEndUserARN
TemplateURL: https://s3.amazonaws.com/CFNTemplate/lambda_resources.stack.yaml
TimeoutInMinutes: 1
HaploLambdaFunction:
Type: "AWS::CloudFormation::Stack"
Properties:
Parameters:
HaploLambdaFuncS3BucketName:
Ref: HaploLambdaFuncS3BucketName
HaploLambdaFuncS3KeyName:
Ref: HaploLambdaFuncS3KeyName
HaploLambdaFuncModuleName:
Ref: HaploLambdaFuncModuleName
KMSAdminUserARN:
Ref: KMSAdminUserARN
KMSEndUserARN:
Ref: KMSEndUserARN
TemplateURL: https://s3.amazonaws.com/CFNTemplate/lambda_resources.stack.yaml
TimeoutInMinutes: 1
Lambda Child Stack (relevant for error):
AWSTemplateFormatVersion: '2010-09-09'
Description: lambda function and execution role stack.
Parameters:
CloudspanLambdaFuncS3BucketName:
Type: String
Default: 'claudia-test-transfer'
CloudspanLambdaFuncS3KeyName:
Default: 'sfn.deployable.zip'
Type: String
CloudspanLambdaFuncModuleName:
Default: 'cloudspan'
Type: String
AlignmentLambdaFuncS3BucketName:
Type: String
Default: 'claudia-test-transfer'
AlignmentLambdaFuncS3KeyName:
Type: String
Default: 'alignment_processing.deployable.zip'
AlignmentLambdaFuncModuleName:
Type: String
Default: 'alignment_processing'
HaploLambdaFuncS3BucketName:
Type: String
Default: 'claudia-test-transfer'
HaploLambdaFuncS3KeyName:
Type: String
Default: 'sentieon_haplotyper.deployable.zip'
HaploLambdaFuncModuleName:
Type: String
Default: 'sentieon_haplotyper'
KMSAdminUserARN:
Type: String
KMSEndUserARN:
Type: String
Resources:
CloudspanLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Handler:
Fn::Join: [ ".", [ Ref: CloudspanLambdaFuncModuleName, "handler"] ]
Role:
Fn::GetAtt: [ CloudspanLambdaExecutionRole, Arn ]
Code:
S3Bucket:
Ref: CloudspanLambdaFuncS3BucketName
S3Key:
Ref: CloudspanLambdaFuncS3KeyName
Runtime: "python3.6"
Timeout: "60"
DependsOn: CloudspanLambdaExecutionRole
AlignmentLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Handler:
Fn::Join: [ ".", [ Ref: AlignmentLambdaFuncModuleName, "handler"] ]
Role:
Fn::GetAtt: [ AlignmentLambdaExecutionRole, Arn ]
Code:
S3Bucket:
Ref: AlignmentLambdaFuncS3BucketName
S3Key:
Ref: AlignmentLambdaFuncS3KeyName
Runtime: "python3.6"
Timeout: "60"
DependsOn: AlignmentLambdaExecutionRole
HaploLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Handler:
Fn::Join: [ ".", [ Ref: HaploLambdaFuncModuleName, "handler"] ]
Role:
Fn::GetAtt: [ HaploLambdaExecutionRole, Arn ]
Code:
S3Bucket:
Ref: HaploLambdaFuncS3BucketName
S3Key:
Ref: HaploLambdaFuncS3KeyName
Runtime: "python3.6"
Timeout: "60"
DependsOn: HaploLambdaExecutionRole
CloudspanLambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: "sts:AssumeRole"
Policies:
- PolicyName: CanListBuckets
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "s3:GetBucketLocation"
- "s3:ListAllMyBuckets"
Resource: "arn:aws:s3:::*"
- PolicyName: CanLog
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:*
Resource: arn:aws:logs:*:*:*
AlignmentLambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: "sts:AssumeRole"
Policies:
- PolicyName: CanListBuckets
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "s3:GetBucketLocation"
- "s3:ListAllMyBuckets"
Resource: "arn:aws:s3:::*"
- PolicyName: CanCallBatch
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "batch:*"
Resource: "*"
- PolicyName: CanLog
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:*
Resource: arn:aws:logs:*:*:*
HaploLambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: "sts:AssumeRole"
Policies:
- PolicyName: CanListBuckets
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "s3:GetBucketLocation"
- "s3:ListAllMyBuckets"
Resource: "arn:aws:s3:::*"
- PolicyName: CanCallBatch
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "batch:*"
Resource: "*"
- PolicyName: CanLog
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:*
Resource: arn:aws:logs:*:*:*
MasterGCPStorageKey:
Type: "AWS::KMS::Key"
Properties:
Description: Symmetric Master Key for GCP Storage Credentials off-line encryption/on-line decryption protocol
Enabled: True
EnableKeyRotation: True
KeyPolicy:
Version: "2012-10-17"
Statement:
- Sid: "Allow Lambda Excution Role access to GCP Storage decryption key"
Effect: "Allow"
Principal:
# ARN of CloudspanLambdaExecutionRole
AWS:
Fn::GetAtt: [ CloudspanLambdaExecutionRole, Arn ]
Action:
- kms:Decrypt
- kms:DescribeKey
# in this context "*" means "this" CMK
Resource: "*"
- Sid: "Allow Administrator to admin the GCP Storage decryption key"
Effect: "Allow"
Principal:
# ARN of the KMS admin IAM user
AWS:
Ref: KMSAdminUserARN
Action:
- "kms:Create*"
- "kms:Describe*"
- "kms:Enable*"
- "kms:List*"
- "kms:Put*"
- "kms:Update*"
- "kms:Revoke*"
- "kms:Disable*"
- "kms:Get*"
- "kms:Delete*"
- "kms:TagResource"
- "kms:UntagResource"
- "kms:ScheduleKeyDeletion"
- "kms:CancelKeyDeletion"
- "kms:Encrypt"
- "kms:Decrypt"
- "kms:ReEncrypt"
- "kms:GenerateDataKey*"
- "kms:DescribeKey"
# in this context "*" means "this" CMK
Resource: "*"
- Sid: "Allow End User to encrypt the GCP Storage creds"
Effect: "Allow"
Principal:
# ARN of the KMS IAM end user
AWS:
Ref: KMSEndUserARN
Action:
- "kms:Encrypt"
- "kms:ReEncrypt"
- "kms:DescribeKey"
# in this context "*" means "this" CMK
Resource: "*"
DependsOn: CloudspanLambdaExecutionRole

I also was getting the following error after re-deploying a CloudFormation stack I had removed (via Serverless):
We encountered the following errors while processing your request:
Policy contains a statement with one or more invalid principals.
In my case, the original role which was assigned to my KMS encryption key was removed. KMS still keeps a reference to the removed role, and apparently adding a newly created role of the same type creates this error.
I solved this by simply removing the old reference to the removed role, under IAM > Encryption Keys > YOUR_KEY_NAME > Key Policy > Key Users

Related

Getting Cloudwatch to send CreateLogGroup messages to EventBridge

I want CloudWatch to send CreateLogGroup messages to EventBridge.
I understand this is possible, but also that Cloudwatch doesn't seem to send these messages by default. It seems you have to configure CloudTrail to get it to forward the message. But I can't find a CloudTrail configuration which works - in general deployment fails with:
AWS::CloudTrail::Trail - "Invalid request provided: Incorrect S3 bucket policy is detected for bucket"
AWSTemplateFormatVersion: '2010-09-09'
Outputs:
HelloFunction:
Value:
Ref: HelloFunction
WatcherFunction:
Value:
Ref: WatcherFunction
WatcherTrailBucket:
Value:
Ref: WatcherTrailBucket
Parameters:
MemorySizeDefault:
Default: '512'
Type: String
RuntimeVersion:
Default: '3.8'
Type: String
TimeoutDefault:
Default: '5'
Type: String
Resources:
HelloFunction:
Properties:
Code:
ZipFile: |
def handler(event, context):
print (event)
Handler: index.handler
MemorySize:
Ref: MemorySizeDefault
Role:
Fn::GetAtt:
- HelloFunctionRole
- Arn
Runtime:
Fn::Sub: python${RuntimeVersion}
Timeout:
Ref: TimeoutDefault
Type: AWS::Lambda::Function
HelloFunctionRole:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: '2012-10-17'
Policies:
- PolicyDocument:
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource: '*'
Version: '2012-10-17'
PolicyName:
Fn::Sub: hello-function-role-policy-${AWS::StackName}
Type: AWS::IAM::Role
WatcherFunction:
Properties:
Code:
ZipFile: |
def handler(event, context):
print (event)
Handler: index.handler
MemorySize:
Ref: MemorySizeDefault
Role:
Fn::GetAtt:
- WatcherFunctionRole
- Arn
Runtime:
Fn::Sub: python${RuntimeVersion}
Timeout:
Ref: TimeoutDefault
Type: AWS::Lambda::Function
WatcherFunctionRole:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: '2012-10-17'
Policies:
- PolicyDocument:
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource: '*'
Version: '2012-10-17'
PolicyName:
Fn::Sub: watcher-function-role-policy-${AWS::StackName}
Type: AWS::IAM::Role
WatcherEventRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.logs
detail-type:
- "AWS API Call via CloudTrail"
detail:
eventName:
- CreateLogGroup
Targets:
- Id:
Fn::Sub: watcher-event-rule-${AWS::StackName}
Arn:
Fn::GetAtt:
- WatcherFunction
- Arn
State: ENABLED
WatcherEventRulePermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
FunctionName:
Ref: WatcherFunction
SourceArn:
Fn::GetAtt:
- WatcherEventRule
- Arn
WatcherTrailBucket:
Type: AWS::S3::Bucket
WatcherTrailBucketPolicy:
DependsOn:
- WatcherTrailBucket
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: WatcherTrailBucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action: s3:GetBucketAcl
Resource: "*"
Condition: {}
- Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action: s3:PutObject
Resource: "*"
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
WatcherTrail:
Type: AWS::CloudTrail::Trail
Properties:
EventSelectors:
- ReadWriteType: All
IsLogging: true
S3BucketName:
Ref: WatcherTrailBucket
IsLogging: true
S3KeyPrefix: logs/
Your WatcherTrail runs before WatcherTrailBucketPolicy, so that's why it fails (CloudFormation does not deploy resource in the order of their definition in the template). Add explicit DependsOn dependency on the bucket policy. Also your WatcherTrailBucketPolicy is incorrect, and trial needs a name. So it should be:
WatcherTrailBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: WatcherTrailBucket
PolicyDocument: !Sub |
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSCloudTrailAclCheck20150319",
"Effect": "Allow",
"Principal": {"Service": "cloudtrail.amazonaws.com"},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::${WatcherTrailBucket}",
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:cloudtrail:${AWS::Region}:${AWS::AccountId}:trail/MyTrial"
}
}
},
{
"Sid": "AWSCloudTrailWrite20150319",
"Effect": "Allow",
"Principal": {"Service": "cloudtrail.amazonaws.com"},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::${WatcherTrailBucket}/logs/AWSLogs/${AWS::AccountId}/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control",
"aws:SourceArn": "arn:aws:cloudtrail:${AWS::Region}:${AWS::AccountId}:trail/MyTrial"
}
}
}
]
}
WatcherTrail:
Type: AWS::CloudTrail::Trail
DependsOn: WatcherTrailBucketPolicy
Properties:
TrailName: MyTrial
EventSelectors:
- ReadWriteType: All
IsLogging: true
S3BucketName:
Ref: WatcherTrailBucket
IsLogging: true
S3KeyPrefix: logs/

Glue connection not working through cloudformation. It is giving error : Unable to resolve any valid connection

My glue connection created through cloudformation is not working whereas if create a glue connection with same configuration through the console it works perfectly fine.
Please find the code for the same :
Resources:
Policy1:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: Policy for glue
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: '*'
Resource: '*'
Role1:
Type: AWS::IAM::Role
DependsOn: Policy1
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- glue.amazonaws.com
- rds.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- !Ref Policy1
GlueConnection:
Type: AWS::Glue::Connection
Properties:
CatalogId: !Ref AWS::AccountId
ConnectionInput:
ConnectionProperties:
JDBC_CONNECTION_URL: "jdbc:mysql://database-2.cxs4adwnjt5i.ap-south-1.rds.amazonaws.com:3306/mydb"
USERNAME: "admin"
PASSWORD: "Admin123"
JDBC_ENFORCE_SSL: False
ConnectionType: JDBC
PhysicalConnectionRequirements:
SecurityGroupIdList:
- sg-065781f0ee39344fa
SubnetId: subnet-0cdac25848264fdb8
Name: rds-1
GlueDatabase:
Type: AWS::Glue::Database
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseInput:
Name: my-rds-glue-1
To fix this you need to include AvailabilityZone in PhysicalConnectionRequirements.
PhysicalConnectionRequirements:
AvailabilityZone: !Select [ 0, !GetAZs '' ]
SecurityGroupIdList:
- !Ref GlueSG
SubnetId: !Ref SubnetId
See more details here:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-glue-connection-physicalconnectionrequirements.html
Until this gets fix the workaround is, like you mentioned, to go in the console and just edit and save the connection.

CloudFormation EventBusPolicy: The relative-id "event-bus/bus_name" is invalid for ARN

According to this doc, I try:
ebMailPolicy:
Type: AWS::Events::EventBusPolicy
Properties:
EventBusName: !Ref ebMail
StatementId: AllowForOrg
Statement:
Effect: Allow
Action: events:PutEvents
Condition:
StringEquals:
"aws:PrincipalOrgID": !Ref OrgId
Principal: "*"
The error is:
The relative-id "event-bus/bus_name" is invalid for ARN "arn:aws:events:eu-central-1:acc_id:event-bus/bus_name"
What am I doing wrong?
The doc is wrong. Correct version:
ebMailPolicy:
Type: AWS::Events::EventBusPolicy
Properties:
EventBusName: !Ref ebMail
StatementId: CrossAccSendEvents
Action: events:PutEvents
Principal: "*"
Condition:
Type: StringEquals
Key: aws:PrincipalOrgID
Value: !Ref OrgId
The AWS document does not explicitly state it but this is what we have working
EventBusPolicy:
Type: AWS::Events::EventBusPolicy
DependsOn: CustomEventBridgeBus
Properties:
StatementId: "AllowSameAWSAccount"
EventBusName: !Ref CustomEventBridgeBus
Statement:
Effect: "Allow"
Principal:
AWS: !ImportValue IntanceRoleArn
Action: "events:PutEvents"
Resource: !GetAtt CustomEventBridgeBus.Arn

Cloudformation !Ref doesn't return the correct value for vpc endpoint

I have a vpc endpoint created with:
ExecuteApiVPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: "*"
Action:
- "execute-api:*"
Resource:
- "*"
ServiceName: !Sub com.amazonaws.${AWS::Region}.execute-api
VpcId: !Ref MyVPC
VpcEndpointType: Interface
SubnetIds:
- !Ref privateSubnet01
- !Ref privateSubnet02
SecurityGroupIds:
- !Ref EndpointSG # has to allow traffic from your VPC
PrivateDnsEnabled: true
and a private API created with:
APIDefinition:
Type: 'AWS::Serverless::Api'
Properties:
StageName: {Ref: Stage}
EndpointConfiguration: PRIVATE
Auth:
ResourcePolicy:
CustomStatements:
- Action: ['execute-api:Invoke']
Effect: Allow
Principal: '*'
Resource: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:/*/*/*"
- Action: ['execute-api:Invoke']
Effect: Deny
Principal: '*'
Resource: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:/*/*/*"
Condition:
ForAllValues:StringNotEquals:
aws:sourceVpce:
- !Ref ExecuteApiVPCEndpoint
The stack was deployed with no error, but the vpce in the resource policy of the API doesn't match with the vpce being created. What's going wrong here? Thanks!

CloudFormation template for Cognito gets NotAuthorizedException error

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