Serverless Appsync IdentityPoolRoleMap deployment error - amazon-cognito

I am using "serverless-appsync-plugin" for generationg Appsync Api and Cogntio Userpool and Federated Identities, everything is getting properly deployed and is working fine except the "IdentityPoolRoleMap", Its giving the below error
"ServerlessError: An error occurred: IdentityPoolRoleMap - null (Service: AmazonCognitoIdentity; Status Code: 500; Error Code: InternalFailure;)"
Adding the sample of IdentityPoolRoleMap
IdentityPoolRoleMap:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId: { Ref: IdentityPool }
Roles:
unauthenticated: { Fn::GetAtt: [ UnauthRole, Arn ]}
authenticated: { Fn::GetAtt: [ AuthRole, Arn ]}
Note: IdentityPool,UnauthRole and AuthRole are properly created.

Related

Aurora PostgreSQL permissions to access s3

Im trying to give my Aurora PostgreSQL permissions to access an s3 bucket. I'm using the serverless framework and have the following code.
RDSCluster:
Type: 'AWS::RDS::DBCluster'
Properties:
MasterUsername: AuserName
MasterUserPassword: Apassword
DBSubnetGroupName:
Ref: RDSClusterGroup
AvailabilityZones:
- eu-central-1a
- eu-central-1b
Engine: aurora-postgresql
EngineVersion: 11.9
EngineMode: provisioned
EnableHttpEndpoint: true
DatabaseName: initialbase
DBClusterParameterGroupName:
Ref: RDSDBParameterGroup
AssociatedRoles:
- RoleArn:
{ Fn::GetAtt: [ AuroraPolicy, Arn ] }
VpcSecurityGroupIds:
- Ref: RdsSecurityGroup
AuroraPolicy:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- rds.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: AuroraRolePolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:AbortMultipartUpload
- s3:GetBucketLocation
- s3:GetObject
- s3:ListBucket
- s3:ListBucketMultipartUploads
- s3:PutObject
Resource:
- { Fn::GetAtt: [ S3BucketEgresbucket, Arn ] }
- Fn::Join:
- ""
- - { Fn::GetAtt: [ S3BucketEgresbucket, Arn ] }
- "/*"
This should grant the DB permission to execute query's using SELECT aws_commons.create_s3_ur
However when I try and deploy I get the error message:
The feature-name parameter must be provided with the current operation for the Aurora (PostgreSQL) engine.
The issue comes from the AssociatedRoles object, cloudformation states that the FeatureName field is not needed however if you are wishing for your cluster to access other AWS services it is required. In this case as I was wanting to have my cluster access an s3 bucket I had to change my AssociatedRoles object so it looked like this:
AssociatedRoles:
- RoleArn: { Fn::GetAtt: [ roleServiceIntegration, Arn ] }
FeatureName: s3Import

Serverless Enterprise deployment

I recently updated to v1.44.0 and used the #serverless/enterprise-plugin and am now unable to deploy. I’m simply trying to create a User Pool, but keep getting an error.
An error occurred: EnterpriseLogAccessIamRole - Policy statement must contain resources. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: dc158686-378c-4d01-97fb-1414d55a735d)
serverless.yml
tenant: [omitted]
app: [omitted]
service: auth
frameworkVersion: ">=1.44.0"
plugins:
- '#serverless/enterprise-plugin'
provider:
name: aws
runtime: nodejs8.10
region: us-east-1
custom:
stage: ${opt:stage, self:provider.stage}
cognito:
app:
userPool: ${self:service}-app-user-pool-${self:custom.stage}
identityPool: AppIdentityPoolDev
resources:
Resources:
AppUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: ${self:custom.cognito.app.userPool}
UsernameAttributes:
- email
AutoVerifiedAttributes:
- email
MobileAppClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: ${self:service}-mobile-app-client-${self:custom.stage}
UserPoolId:
Ref: AppUserPool
GenerateSecret: true
Outputs:
AppUserPool:
Value:
Ref: AppUserPool
MobileAppClient:
Value:
Ref: MobileAppClient

How to define CF resource as function event source in serverless framework

I'm trying to create a AWS Lambda with the serverless framework. The Lambda is triggered through an AWS IoT Topic Rule. In case the execution of the Rule fails I want to have an error action executed. The entire configuration should take place within the serverless.yml.
As far as I can tell from the documentation there is no option to describe an errorAction for an iot event:
functions:
foobar:
events:
- iot:
errorAction: ?
It is possible though to define a Cloud Formation resource with an ErrorAction inside the serverless.yml:
resources:
Resources:
FoobarIotTopicRule1:
Type: AWS::IoT::TopicRule
Properties:
ErrorAction:
Republish:
RoleArn: arn:aws:iam::1234567890:role/service-role/iot_execution_role
Topic: FAILURE
But then I don't know how to link the resource to act as a trigger of the Lambda function.
functions:
foobar:
handler: index.handler
events:
- iot:
name: iot_magic_rule
sql: "SELECT * FROM 'my/dedicated/topic'"
enabled: true
sqlVersion: '2016-03-23'
resources:
Resources:
FoobarIotTopicRule1:
Type: AWS::IoT::TopicRule
Properties:
RuleName: iot_magic_rule
TopicRulePayload:
AwsIotSqlVersion: '2016-03-23'
RuleDisabled: false
Sql: "SELECT * FROM 'my/dedicated/topic'"
ErrorAction:
Republish:
RoleArn: arn:aws:iam::1234567890:role/service-role/iot_execution_role
Topic: FAILURE
With the above configuration, trying to deploy on AWS fails as Cloud Formation tries to create the AWS IoT Topic Rule twice. Once for the definition in events and once as the defined resource FoobarIoTTopicRule1.
EDIT1
Defining the Lambda action inside the IoTTopicRule resource, creates the rule as intended, with Lambda action and error event. Unfortunately the rule does not show up as a trigger within the Lambda.
To be able to define an AWS IoT Topic Rule with an ErrorAction that will also show up as a trigger event on AWS Lambda, the configuration should look somewhat like this:
functions:
foobar:
handler: index.handler
resources:
Resources:
FoobarIotTopicRule1:
Type: AWS::IoT::TopicRule
Properties:
RuleName: iot_magic_rule
TopicRulePayload:
AwsIotSqlVersion: '2016-03-23'
RuleDisabled: false
Sql: "SELECT * FROM 'my/dedicated/topic'"
Actions:
- Lambda:
FunctionArn: { "Fn::GetAtt": ['FoobarLambdaFunction', 'Arn']}
ErrorAction:
Republish:
RoleArn: arn:aws:iam::1234567890:role/service-role/iot_execution_role
Topic: FAILURE
FoobarLambdaPermissionIotTopicRule1:
Type: AWS::Lambda::Permission
Properties:
FunctionName: { "Fn::GetAtt": [ "FoobarLambdaFunction", "Arn" ] }
Action: lambda:InvokeFunction
Principal: { "Fn::Join": ["", [ "iot.", { "Ref": "AWS::URLSuffix" } ]]}
SourceArn:
Fn::Join:
- ""
- - "arn:"
- "Ref": "AWS::Partition"
- ":iot:"
- "Ref": "AWS::Region"
- ":"
- "Ref": "AWS::AccountId"
- ":rule/"
- "Ref": "FoobarIotTopicRule1"

unable to add notificationconfiguration to s3 bucket

Created cloud formation template to create bucket with notification.
Following is code:
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
CBRS3ToS3IADelay:
Description: Number of days before an S3 object is transitioned from S3 to S3-IA
Type: Number
Default: 365
CBRS3ToGlacierDelay:
Description: Number of days before an S3-IA object is transitioned from S3-IA to Glacier.
Type: Number
Default: 1460
CBRBucketName:
Description: S3 bucket name
Type: String
Default: "my-bucket-test0011"
Resources:
CBRS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName:
Ref: CBRBucketName
AccessControl: Private
LifecycleConfiguration:
Rules:
- Id: CbrCertReportGlacierArchiveRule
Status: Enabled
Transitions:
- StorageClass: STANDARD_IA
TransitionInDays: !Ref CBRS3ToS3IADelay
- StorageClass: GLACIER
TransitionInDays: !Ref CBRS3ToGlacierDelay
NotificationConfiguration:
LambdaConfigurations:
-
Function: "arn:aws:lambda:xxxx:xxxx:function:xxxx"
Event: "s3:ObjectCreated:Put"
Filter:
S3Key:
Rules:
-
Name: suffix
Value: ".gz"
Tags:
- Key: PRODUCT
Value: CRAWS
VersioningConfiguration:
Status: Enabled
Code working with notification block.
But above template is not working with notification.
Getting following error:
Unable to validate the following destination configurations (Service: Amazon S3; Status Code: 400; Error Code: InvalidArgument
I able to do from console.
Anyone help me to fix this issue?
this is late, so more of answering myself for this question (just managed to fix the same problem): it fails due to a preliminary check on s3 to invoke that lambda function, we will need this:
CBRS3BucketCanInvokeFunctionX:
Type: 'AWS::Lambda::Permission'
Properties:
FunctionName: ARN_OF_FUNCTION_X
Action: 'lambda:InvokeFunction'
Principal: s3.amazonaws.com
SourceAccount: !Ref 'AWS::AccountId'
SourceArn: !Sub 'arn:aws:s3:::${CBRBucketName}'
your CBRS3Bucket will also need to let above resource run first:
CBRS3Bucket:
Type: AWS::S3::Bucket
DependsOn: CBRS3BucketCanInvokeFunctionX
Try taking the .gz and put in just gz.

AWS Api Gateway proxy resource using Cloudformation?

I'm trying to proxy an S3 bucket configured as a website from an API Gateway endpoint. I configured an endpoint successfully using the console, but I am unable to recreate the configuration using Cloudformation.
After lots of trial and error and guessing, I've come up with the following CF stack template that gets me pretty close:
Resources:
Api:
Type: 'AWS::ApiGateway::RestApi'
Properties:
Name: ApiDocs
Resource:
Type: 'AWS::ApiGateway::Resource'
Properties:
ParentId: !GetAtt Api.RootResourceId
RestApiId: !Ref Api
PathPart: '{proxy+}'
RootMethod:
Type: 'AWS::ApiGateway::Method'
Properties:
HttpMethod: ANY
ResourceId: !GetAtt Api.RootResourceId
RestApiId: !Ref Api
AuthorizationType: NONE
Integration:
IntegrationHttpMethod: ANY
Type: HTTP_PROXY
Uri: 'http://my-bucket.s3-website-${AWS::Region}.amazonaws.com/'
PassthroughBehavior: WHEN_NO_MATCH
IntegrationResponses:
- StatusCode: 200
ProxyMethod:
Type: 'AWS::ApiGateway::Method'
Properties:
HttpMethod: ANY
ResourceId: !Ref Resource
RestApiId: !Ref Api
AuthorizationType: NONE
RequestParameters:
method.request.path.proxy: true
Integration:
CacheKeyParameters:
- 'method.request.path.proxy'
RequestParameters:
integration.request.path.proxy: 'method.request.path.proxy'
IntegrationHttpMethod: ANY
Type: HTTP_PROXY
Uri: 'http://my-bucket.s3-website-${AWS::Region}.amazonaws.com/{proxy}'
PassthroughBehavior: WHEN_NO_MATCH
IntegrationResponses:
- StatusCode: 200
Deployment:
DependsOn:
- RootMethod
- ProxyMethod
Type: 'AWS::ApiGateway::Deployment'
Properties:
RestApiId: !Ref Api
StageName: dev
Using this template I can successfully get the root of the bucket website, but the proxy resource gives me a 500:
curl -i https://abcdef.execute-api.eu-west-1.amazonaws.com/dev/index.html
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 36
Connection: keep-alive
Date: Mon, 11 Dec 2017 16:36:02 GMT
x-amzn-RequestId: 6014a809-de91-11e7-95e4-dda6e24d156a
X-Cache: Error from cloudfront
Via: 1.1 8f6f9aba914cc74bcbbf3c57e10df26a.cloudfront.net (CloudFront)
X-Amz-Cf-Id: TlOCX3eemHfY0aiVk9MLCp4qFzUEn5I0QUTIPkh14o6-nh7YAfUn5Q==
{"message": "Internal server error"}
I have no idea how to debug that 500.
To track down what may be wrong, I've compared the output of aws apigateway get-resource on the resource I created manually in the console (which is working) with the one Cloudformation made (which isn't). The resources look exactly alike. The output of get-method however, is subtly different, and I'm not sure it's possible to make them exactly the same using Cloudformation.
Working method configuration:
{
"apiKeyRequired": false,
"httpMethod": "ANY",
"methodIntegration": {
"integrationResponses": {
"200": {
"responseTemplates": {
"application/json": null
},
"statusCode": "200"
}
},
"passthroughBehavior": "WHEN_NO_MATCH",
"cacheKeyParameters": [
"method.request.path.proxy"
],
"requestParameters": {
"integration.request.path.proxy": "method.request.path.proxy"
},
"uri": "http://muybucket.s3-website-eu-west-1.amazonaws.com/{proxy}",
"httpMethod": "ANY",
"cacheNamespace": "abcdefg",
"type": "HTTP_PROXY"
},
"requestParameters": {
"method.request.path.proxy": true
},
"authorizationType": "NONE"
}
Configuration that doesn't work:
{
"apiKeyRequired": false,
"httpMethod": "ANY",
"methodIntegration": {
"integrationResponses": {
"200": {
"responseParameters": {},
"responseTemplates": {},
"statusCode": "200"
}
},
"passthroughBehavior": "WHEN_NO_MATCH",
"cacheKeyParameters": [
"method.request.path.proxy"
],
"requestParameters": {
"integration.request.path.proxy": "method.request.path.proxy"
},
"uri": "http://mybucket.s3-website-eu-west-1.amazonaws.com/{proxy}",
"httpMethod": "ANY",
"requestTemplates": {},
"cacheNamespace": "abcdef",
"type": "HTTP_PROXY"
},
"requestParameters": {
"method.request.path.proxy": true
},
"requestModels": {},
"authorizationType": "NONE"
}
The differences:
The working configuration has responseTemplates set to "application/json": null. As far as I can tell, there's no way to set a mapping explicitly to null using Cloudformation. My CF method instead just has an empty object here.
My CF method has "responseParameters": {},, while the working configuration does not have responseParameters at all
My CF method has "requestModels": {},, while the working configuration does not have requestModels at all
Comparing the two in the console, they are seemingly exactly the same.
I'm at my wits end here: what am I doing wrong? Is this possible to achieve using Cloudformation?
Answer: The above is correct. I had arrived at this solution through a series of steps, and re-applied the template over and over. Deleting the stack and deploying it anew with this configuration had the desired effect.