ResourceRegistrationFailureException when calling the RegisterThing operation - thing groups conflict - amazon-web-services

I am getting the following error when trying to use the RegisterThings action from AWS IoT. Within the API, call, I am trying to set the thing groups but getting the following error:
An error occurred (ResourceRegistrationFailureException) when calling the RegisterThing operation: Existing ThingGroups: [] conflict with ThingGroups: [mythingggroup] in Template
Here is my provisioning template:
provision_json = json.dumps({
"Parameters": {
"ThingName": {
"Type": "String"
},
"ThingGroup": {
"Type": "String"
},
"CertificateId": {
"Type": "String"
},
"PolicyName": {
"Type": "String"
},
"AssumeRolePolicyName": {
"Type": "String"
}
},
"Resources": {
"Thing": {
"Type": "AWS::IoT::Thing",
"Properties": {
"ThingName": {
"Ref": "ThingName"
},
"ThingGroups": [{
"Ref": "ThingGroup"
}]
},
"OverrideSettings" : {
"ThingGroups" : "REPLACE"
}
},
"Certificate": {
"Type": "AWS::IoT::Certificate",
"Properties": {
"CertificateId": {
"Ref": "CertificateId"
}
}
},
"DevicePolicy": {
"Type": "AWS::IoT::Policy",
"Properties": {
"PolicyName": {
"Ref": "PolicyName"
}
}
},
"TESAssumeRolePolicy": {
"Type": "AWS::IoT::Policy",
"Properties": {
"PolicyName": {
"Ref": "AssumeRolePolicyName"
}
}
}
}
})
then I call the boto3 client like this:
iot = boto3.client("iot")
response = iot.register_thing(
templateBody=provision_json,
parameters={
"CertificateId": "1234",
"ThingName": "mythingname",
"ThingGroup": "mythinggroupname",
"PolicyName": "mypolicyname",
"AssumeRolePolicyName": "anotherpolicyname"
}
)
I thought this might be a permissions error, but even after I give the caller iot:*, I still have the same issue.
AWS isn't providing great documentation on why this error is occurring. Does anyone have any ideas?

Related

AWS SAM/Cloudformation configure API Gateway to point to lambda function version

I am currently trying to enable provisioned concurrency for my AWS lambda function. I already figured I can only do this on either a Lambda Function Version or a Lambda Function Alias. But I am having a hard time to point my API Gateway to this version, it seems to always point to the base function, not the version.
In the UI I can easily attach my Lambda Function Version to an API Gateway Endpoint, but I cannot figure out how to do it in my SAM Template.
This is what I currently have:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Transform": "AWS::Serverless-2016-10-31",
"Description": "Desc.",
"Parameters": { },
"Resources": {
"MyLambdaFunction": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Runtime": "dotnetcore3.1",
"CodeUri": "MyCodeUri",
"MemorySize": 1024,
"Timeout": 30,
"Events": {
"HttpEvent1": {
"Type": "Api",
"Properties": {
"Path": "/v1/test",
"Method": "GET",
"RestApiId": {
"Ref": "ApiGateway"
}
}
}
},
"Handler": "MyNamespace::MyNamespace.MyFunc::RunAsync"
}
},
"MyLambdaFunctionConcurrentV1": {
"Type": "AWS::Lambda::Version",
"Properties": {
"FunctionName": {
"Ref": "MyLambdaFunction"
},
"ProvisionedConcurrencyConfig": {
"ProvisionedConcurrentExecutions": 1
}
}
},
"ApiGateway": {
"Type": "AWS::Serverless::Api",
"Properties": {
"StageName": {
"Ref": "ApiStageName"
},
"Cors": {
"AllowCredentials": true,
"AllowHeaders": "'*'",
"AllowMethods": "'*'",
"AllowOrigin": "'*'",
"MaxAge": "'600'"
}
}
}
},
"Outputs": {
"ApiUrl": {
"Description": "API Gateway Endpoint URL",
"Value": {
"Fn::Sub": "https://${ApiGateway}.execute-api.${AWS::Region}.${AWS::URLSuffix}/${ApiStageName}"
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}-ApiUrl"
}
}
}
}
}
So I am fine to deploy my Lambda function, my API Gateway and my version. But I cannot figure out how to link the API Gateway to my version.
I just figured out I was looking at the wrong documentation. As I have a SAM template and not a Cloudformation template I can use the AutoPublishAlias together with the ProvisionedConcurrencyConfig directly attached to my lambda function.
Knowing this, the solution was way easier - the version is not necessary as the SAM template version of the AWS::Serverless::Function supports ProvisionedConcurrencyConfig directly - as long as AutoPublishAlias is set as well.
This is my working template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Transform": "AWS::Serverless-2016-10-31",
"Description": "Desc.",
"Parameters": { },
"Resources": {
"MyLambdaFunction": {
"Type": "AWS::Serverless::Function",
"Properties": {
"AutoPublishAlias": "V1",
"ProvisionedConcurrencyConfig": {
"ProvisionedConcurrentExecutions": 1
},
"Runtime": "dotnetcore3.1",
"CodeUri": "MyCodeUri",
"MemorySize": 1024,
"Timeout": 30,
"Events": {
"HttpEvent1": {
"Type": "Api",
"Properties": {
"Path": "/v1/test",
"Method": "GET",
"RestApiId": {
"Ref": "ApiGateway"
}
}
}
},
"Handler": "MyNamespace::MyNamespace.MyFunc::RunAsync"
}
},
"ApiGateway": {
"Type": "AWS::Serverless::Api",
"Properties": {
"StageName": {
"Ref": "ApiStageName"
},
"Cors": {
"AllowCredentials": true,
"AllowHeaders": "'*'",
"AllowMethods": "'*'",
"AllowOrigin": "'*'",
"MaxAge": "'600'"
}
}
}
},
"Outputs": {
"ApiUrl": {
"Description": "API Gateway Endpoint URL",
"Value": {
"Fn::Sub": "https://${ApiGateway}.execute-api.${AWS::Region}.${AWS::URLSuffix}/${ApiStageName}"
},
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}-ApiUrl"
}
}
}
}
}
Side note: I also tried to apply the same AutoPublishAlias to multiple functions in the same stack - it works, so it does not need to be unique.

Value of property Subscription must be a list of objects

Using aws cloud formation designer to make a simple SNS topic with subscription and queue for SES. I connected the components but my stack fails to create the subscription.
Error: Value of property Subscription must be a list of objects
"Resources": {
"SNST3F2X9": {
"Type": "AWS::SNS::Topic",
"Properties": {
"DisplayName": "EmailBounceTopic",
"Subscription": [
"EmailBounceSubscription"
],
"TopicName": "EmailBounceTopic"
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "094fd7f3-2e35-4219-8f87-07ad335f85bb"
}
}
},
"SNST3FDSS": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"EndPoint": "BounceQueue",
"Protocol": "SQS",
"RawMessageDelivery": true,
"TopicArn": {
"Ref": "SNST3F2X9"
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "b9524cd1-7d7a-46a6-9c34-33ceccccf3d4"
}
}
},
"SQSQ3OZGY": {
"Type": "AWS::SQS::Queue",
"Properties": {
"QueueName": "BounceQueue"
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "d5a6cfd6-4b52-486a-97c1-4021528c32fc"
}
},
"DependsOn": [
"SNST3FDSS"
]
}
}
Your current Subscription is:
"Subscription": [
"EmailBounceSubscription"
]
But Subscription should be a list of objects in the form of (example):
"Subscription" : [{
"Endpoint" : "EmailBounceSubscription",
"Protocol" : "email"
}

AWS and CloudFormation: How to attach a Virtual Private Gateway to a Routing Table?

I'm trying to attach a Virtual Private Gateway to a Routing Table with CloudFormation
The following is the Route table JSON I have...
"PrivateRouteTable": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": {
"Ref": "VPC"
},
"Tags": [{
"Key": "Name",
"Value": "Private_RouteTable-AZ-A"
}]
}
},
"DefaultPrivateRoute": {
"Type": "AWS::EC2::Route",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTable"
},
"DestinationCidrBlock": "0.0.0.0/0",
"NatGatewayId": {
"Ref": "NatGateway"
}
}
},
"PrivateSubnetRouteTableAssociation": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTable"
},
"SubnetId": {
"Ref": "PrivateSN"
}
}
}
And this is the Virtual Private Gateway JSON I have..
"VirtualPrivateGateway": {
"Type": "AWS::EC2::VPNGateway",
"Properties": {
"Type": "ipsec.1",
"Tags": [{
"Key": "Name",
"Value": "Virtual Private Gateway"
}]
}
},
"AttachmentVPNGateway": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"VpcId": {
"Ref": "VPC"
},
"VpnGatewayId": {
"Ref": "VirtualPrivateGateway"
}
}
},
"VPNConnection": {
"Type": "AWS::EC2::VPNConnection",
"Properties": {
"Type": "ipsec.1",
"CustomerGatewayId": {
"Ref": "CustomerGateway"
},
"StaticRoutesOnly": true,
"Tags": [{
"Key": "Name",
"Value": "VPN_Connection"
}],
"VpnGatewayId": {
"Ref": "VirtualPrivateGateway"
}
}
}
There's more as well that creates the VPC, Subnet, etc, but I've left it out for simplicity sake.
The error happens if I try attach the VPG to the Route table with the following JSON...
"VPGPrivateRoute": {
"Type": "AWS::EC2::Route",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTable"
},
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": {
"Ref": "VirtualPrivateGateway"
}
}
}
The error I receive from CloudFormation...
The gateway ID 'vgw-xxxxxxxxxxx' does not exist (Service: AmazonEC2; Status Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID: e29700b2-2d76-4e19-9d13-b6f84e22b01c)
The documentation does say that I should be use "GatewayId" to associate a VPG to a route table.
I think there should be DependsOn on the route table:
A VPN gateway route propagation depends on a VPC-gateway attachment when you have a VPN gateway.
Maybe the following will help:
"VPGPrivateRoute": {
"Type": "AWS::EC2::Route",
"DependsOn" : "AttachmentVPNGateway",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTable"
},
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": {
"Ref": "VirtualPrivateGateway"
}
}
}

Import s3 bucket from one stack to other stack

I have created S3 Bucket with deletepolicy retain using cloud formation, I Have exported the created bucket using Export in outputs in cloudformation.
Now I want to use the same s3 bucket in another stack using import
Cloud formation for s3:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Creates an S3 bucket to be used for static content/website hosting.",
"Parameters": {
"AssetInsightId": {
"Description": "Asset Insight ID",
"Type": "String",
"Default": "206153"
},
"ResourceOwner": {
"Description": "tr:resource-owner",
"Type": "String",
"Default": "####"
},
"EnvironmentType": {
"Description": "tr:environment-type",
"Default": "preprod",
"Type": "String",
"AllowedValues": ["preprod", "prod"],
"ConstraintDescription": "must specify preprod, prod."
}
},
"Resources": {
"S3Bucket": {
"Type": "AWS::S3::Bucket",
"DeletionPolicy": "Retain",
"Properties": {
"BucketName": {
"Fn::Sub": "a${AssetInsightId}-s3bucket-${EnvironmentType}"
},
"Tags": [{
"Key": "tr:application-asset-insight-id",
"Value": {
"Fn::Sub": "${AssetInsightId}"
}
}, {
"Key": "tr:environment-type",
"Value": {
"Fn::Sub": "${EnvironmentType}"
}
}
]
}
}
},
"Outputs": {
"S3Bucket": {
"Description": "Information about the value",
"Description": "Name of the S3 Resource Bucket",
"Value": "!Ref S3Bucket",
"Export": {
"Name": "ExportS3Bucket"
}
}
}
}
cloud formation to use created s3 bucket from another template with import
Second template :
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Creates an S3 apigateway to be used for static content/website hosting.",
"Parameters": {
"AssetInsightId": {
"Description": "Asset Insight ID",
"Type": "String",
"Default": "206153"
},
"ResourceOwner": {
"Description": "tr:resource-owner",
"Type": "String",
"Default": "swathi.koochi#thomsonreuters.com"
},
"EnvironmentType": {
"Description": "tr:environment-type",
"Default": "preprod",
"Type": "String",
"AllowedValues": ["preprod", "prod"],
"ConstraintDescription": "must specify preprod, prod."
},
"endpointConfiguration": {
"Description": "tr:endpoint-configuration",
"Default": "REGIONAL",
"Type": "String",
"AllowedValues": ["REGIONAL", "EDGE"],
"ConstraintDescription": "must specify REGIONAL, EDGE."
}
},
"Resources": {
"S3BucketImport": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": {"Fn::ImportValue" : "ExportS3Bucket"}
}
},
"APIGateWayRestResourceRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "MyAPI",
"Description": "API Gateway rest api with cloud formation",
"EndpointConfiguration": {
"Types": [{
"Ref": "endpointConfiguration"
}
]
}
}
},
"APIGateWayResource": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {
"Ref": "APIGateWayRestResourceRestApi"
},
"ParentId": {
"Fn::GetAtt": ["APIGateWayRestResourceRestApi", "RootResourceId"]
},
"PathPart": "test"
}
},
"APIGatewayPostMethod": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"AuthorizationType": "NONE",
"HttpMethod": "POST",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Sub": "arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-2:861756181523:function:GreetingLambda/invocations"
}
},
"MethodResponses": [{
"ResponseModels": {
"application/json": {
"Ref": "PostMethodResponse"
}
},
"StatusCode": 200
}
],
"ResourceId": {
"Ref": "APIGateWayResource"
},
"RestApiId": {
"Ref": "APIGateWayRestResourceRestApi"
}
}
},
"PostMethodResponse": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "PostMethodResponse",
"RestApiId": {
"Ref": "APIGateWayRestResourceRestApi"
},
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "PostMethodResponse",
"type": "object",
"properties": {
"Email": {
"type": "string"
}
}
}
}
},
"RestApiDeployment": {
"DependsOn": "APIGatewayPostMethod",
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "APIGateWayRestResourceRestApi"
}
}
},
"RestAPIStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "RestApiDeployment"
},
"MethodSettings": [{
"DataTraceEnabled": true,
"HttpMethod": "*",
"ResourcePath": "/*"
}
],
"RestApiId": {
"Ref": "APIGateWayRestResourceRestApi"
},
"StageName": "Latest"
}
},
"APIGateWayDomainName": {
"Type": "AWS::ApiGateway::DomainName",
"Properties": {
"CertificateArn": {
"Ref": "myCertificate"
},
"DomainName": {
"Fn::Join": [".", [{
"Ref": "AssetInsightId"
}, {
"Ref": "EnvironmentType"
}, "api"]]
},
"EndpointConfiguration": {
"Types": [{
"Ref": "endpointConfiguration"
}
]
}
}
},
"myCertificate": {
"Type": "AWS::CertificateManager::Certificate",
"Properties": {
"DomainName": {
"Fn::Join": [".", [{
"Ref": "AssetInsightId"
}, {
"Ref": "EnvironmentType"
}, "api"]]
}
}
}
}
}
when I/m trying to import using Import Value, I'm getting error saying
S3BucketImport
CREATE_FAILED Bad Request (Service: Amazon S3; Status Code: 400; Error Code: 400 Bad Request; Request ID: 9387EBE0E472E559; S3 Extended Request ID: o8EbE20IOoUgEMwXc7xVjuoyQT03L/nnQ7AsC94Ff1S/PkE100Imeyclf1BxYeM0avuYjDWILxA=)
As #Jarmod correctly pointed out,
In your first template, export the s3 bucket name using { "Ref" : ",S3Bucket" }
In your second template, you don't have to create the bucket again.you can use the exported value from the first template if you want to refer the bucket name from resources. But i don't see any of the resources in the second template refer the S3 bucket name.

Cloudformation Property validation failure: Encountered unsupported properties

I'm trying to create a nested stack with the root stack looks like this:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"DynamoDBTable": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"Parameters": {
"TableName": {
"Fn::Sub": "${AWS::StackName}"
}
},
"TemplateURL": "https://s3.amazonaws.com/my-templates-bucket/dynamodb.json"
}
},
"S3WebsiteReact": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"Parameters": {
"BucketName": {
"Fn::Sub": "${AWS::StackName}-website"
}
},
"TemplateURL": "https://s3.amazonaws.com/my-templates-bucket/s3-static-website-react.json"
}
},
"S3UploadBucket": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"Parameters": {
"BucketName": {
"Fn::Sub": "${AWS::StackName}-upload"
}
},
"TemplateURL": "https://s3.amazonaws.com/my-templates-bucket/s3-with-cors.json"
}
},
"Cognito": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": "DynamoDBTable",
"Properties": {
"Parameters": {
"CognitoUserPoolName": {
"Fn::Join" : ["",
{
"Fn::Split": ["-", {
"Ref": "AWS::StackName"
}]
}
]
}
},
"TemplateURL": "https://s3.amazonaws.com/my-templates-bucket/cognito.json"
}
},
"ApiGateway": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": ["DynamoDBTable", "Cognito"],
"Properties": {
"Parameters": {
"ApiGatewayName": {
"Fn::Sub": "${AWS::StackName}-api"
},
"CognitoUserPoolArn": {
"Fn::GetAtt": [ "Cognito", "Outputs.UserPoolArn" ]
},
"DynamoDBStack": {
"Fn::GetAtt": [ "DynamoDBTable", "Outputs.DDBStackName" ]
}
},
"TemplateURL": "https://s3.amazonaws.com/my-templates-bucket/api-gateway.json"
}
},
"IdentityPool": {
"Description": "Cognito Identity Pool. Must be created after User Pool and API Gateway.",
"Type": "AWS::Cognito::IdentityPool",
"DependsOn": ["Cognito", "ApiGateway", "S3UploadBucket"],
"Properties": {
"Parameters": {
"AppClientId": {
"Fn::GetAtt": [ "Cognito", "Outputs.AppClientId" ]
},
"UserPoolProviderName": {
"Fn::GetAtt": [ "Cognito", "Outputs.ProviderName" ]
},
"UserPoolName": {
"Fn::GetAtt": [ "Cognito", "Outputs.UserPoolName" ]
},
"UploadBucketName": {
"Fn::GetAtt": [ "S3UploadBucket", "Outputs.UploadBucketName" ]
},
"ApiGatewayId": {
"Fn::GetAtt": [ "ApiGateway", "Outputs.ApiGatewayId" ]
}
},
"TemplateURL": "https://s3.amazonaws.com/my-templates-bucket/identity-pool.json"
}
}
},
"Outputs": {
}
}
And I get this error:
2019-06-19 14:45:14 UTC-0400 IdentityPool CREATE_FAILED Property validation failure: [Encountered unsupported properties in {/}: [TemplateURL, Parameters]]
It looks like my identity pool stack has some issues with the parameters. But the identity pool stack parameters look like this:
"Parameters" : {
"AppClientId": {
"Description": "ID of the App Client of the Cognito User Pool passed into this stack.",
"Type": "String"
},
"UserPoolProviderName": {
"Description": "Cognito User Pool Provider name passed into this stack.",
"Type": "String"
},
"UserPoolName": {
"Description": "Cognito User Pool Name passed into this stack.",
"Type": "String"
},
"UploadBucketName": {
"Description": "Name of the bucket that is used to upload files to.",
"Type": "String"
},
"ApiGatewayId": {
"Description": "ID of the API Gateway created for the stack.",
"Type": "String"
}
},
The funny thing is: I tried creating each stack on its own, then passed the outputs from them as parameters to the stacks that need those parameters and every single stack was created successfully without any problems.
I've tried to look for what is unsupported but was unable to find any answers.
The error:
[Encountered unsupported properties in {/}: [TemplateURL, Parameters]]
Says that those two properties are unsupported. Unlike all the rest of the resources declared in your template which also use those two properties, this resource is a AWS::Cognito::IdentityPool, while the rest are all of type AWS::CloudFormation::Stack.
Those two properties are only valid on the AWS::CloudFormation::Stack type, hence the validation error.