In the AWS account that you want other accounts to emit CloudFormation outputs to
-
Create a DynamoDB table called
cloudformation-stack-emissions- This can be done by deploying the
cloudformation-stack-emissions-dynamodb.ymlCloudFormation template in the web console with this button, or by creating the table in the web console or on the command line. Only one DynamoDB stack in one region need be deployed in the AWS account.
- This can be done by deploying the
-
Deploy the CloudFormation template
cloudformation-sns-emission-consumer-role.ymlwith this buttonin a single region which will create an IAM Role used by the Lambda function. Only one IAM Role stack in one region need be deployed in the AWS account.
-
Deploy the CloudFormation template
cloudformation-sns-emission-consumer.ymlwith these buttons once in every region that you need to receive CloudFormation outputs in. (You're welcome to deploy the template in regions other than those listed below).Since CloudFormation custom resources can only emit to SNS topics in the same region, a separate SNS topic must be deployed in every region that you use. This stack creates
- An SNS Topic to which other accounts will emit events to and Topic Policy
- A Lambda function subscribed to that SNS Topic
Create a CloudFormation template containing
- A CloudFormation Custom Resource
with the following properties
ServiceToken: The SNS ARN of the SNS topic you created when deploying the infrastructure- An optional
categoryfield. This field is indexed in DynamoDB and as a result items can be queried by category. If nocategoryis set in the resource, it will be set to the valuegeneralin the DB record. In the example below thecategoryvalue is set toMy Category - An arbitrary number of additional optional key value pairs. In the example below
there's a single key value pair with a key of
exampleKeyand value ofExample Value
Note : You may want to constrain users from deploying this template in regions where you've not deployed an SNS topic to receive stack emissions. One way to do this is with a region Mapping
AWSTemplateFormatVersion: 2010-09-09
Resources:
PublishExampleToSNS:
Type: Custom::PublishToSNS
Version: '1.0'
Properties:
ServiceToken: !Join [ ':', [ 'arn:aws:sns', !Ref 'AWS::Region', '012345678901', 'cloudformation-stack-emissions' ] ]
category: My Category
exampleKey: Example ValueData is queryable by either the aws-account-id or the category fields.
You can fetch data from the DynamoDB table with the aws command line. To fetch
the exampleKey value for all emissions in account 012345678901 query like
this
aws dynamodb query --table-name cloudformation-stack-emissions \
--expression-attribute-names '{"#a": "aws-account-id"}' \
--expression-attribute-values '{":i": {"S": "012345678901"}}' \
--key-condition-expression "#a = :i" \
--projection-expression exampleKey \
--output text --query 'Items[].exampleKey.S'
or for all accounts given category value of testing query the secondary
global index category like
aws dynamodb query --table-name cloudformation-stack-emissions \
--index-name category \
--expression-attribute-names '{"#c": "category"}' \
--expression-attribute-values '{":v": {"S": "My Category"}}' \
--key-condition-expression "#c = :v" \
--projection-expression exampleKey \
--output text --query 'Items[].exampleKey.S'
Or to get exampleKey from a specific record based on an AWS account ID and category
aws dynamodb query --table-name cloudformation-stack-emissions \
--expression-attribute-names '{"#a": "aws-account-id", "#c": "category"}' \
--expression-attribute-values '{":i": {"S": "012345678901"}, ":v": {"S": "My Category"}}' \
--key-condition-expression "#a = :i" \
--filter-expression "#c = :v" \
--projection-expression exampleKey \
--output text --query 'Items[].exampleKey.S'
The following attributes are always set
aws-account-id: The AWS account ID in which the CloudFormation stack was deployedid: The GUID of the CloudFormation stack combined with the Logical Resource name of the CloudFormation resource, separated by a+character. Example :6ff5f130-20d6-11e9-b98a-0a1528792fce+PublishTestToSNS
The following attributes are set if they aren't passed in the Properties of
the CloudFormation stack
category: If it's not defined in the CloudFormation template, it's set togeneralregion: The AWS region in which the CouldFormation stack was deployedstack-name: The name of the CloudFormation stacklast-updated: The datetime that the record was last updated in UTC time
- Table name :
cloudformation-stack-emissions - Partition key :
aws-account-idwhich contains the AWS Account ID of the AWS account that contains the CloudFormation stack which is emitting data - Sort key :
idwhich contains the the GUID of the CloudFormation stack combined with the Logical Resource name of the CloudFormation resource, separated by a+character. - Global Secondary Index :
category- Partition key :
categorywhich contains the category set in the CloudFormation template or the default ofgeneral - Sort key :
id
- Partition key :
- Attributes : All additional Resource Properties of the CloudFormation Custom Resource are inserted into a DynamoDB Item as attributes (key value pairs)
