CloudFormation support for SNS Application Platform

Marcin Sodkiewicz
3 min readJan 13, 2023

TLDR; There is no CloudFormation support for SNS platform application, but you can make it work with custom resource that can be found under: https://github.com/SodaDev/sns-platform-application

Motivation

I had to create infrastructure for sending push notifications to mobile devices. I decided to do it using SNS with Firebase. You can set it up in SNS using Platform Applications. That way you can deliver push notifications to mobile devices by just publishing messages to your SNS topic.

Unfortunately there is no support in CloudFormation for platform applications, so I decided to publish custom resource that can help you with it in similar fashion as with SSO resources some time ago.

Solution

All necessary operations are available and easy to use in AWS SDK, so creating that lambda was quite trivial. Yet, each platforms have different set of parameters that has to be provided. So you have to go through AWS Docs and check how to integrate your platform of choice.

How can I use it?

Deploy custom resource lambda to your account

You need to have custom resource lambda in your account to make it work. Just deploy custom resource lambda in your account according to: https://github.com/SodaDev/sns-platform-application#how-to-deploy-it.

Custom resource lambda exports it’s arn in Outputs section. When you are creating custom resource you have to specify which lambda should handle that particular resource through ServiceToken field. In case of platform application lambda it should be done like:

ApplicationPlatform:
Type: Custom::SNSApplicationPlatform
Properties:
ServiceToken:
Fn::ImportValue: SNS::PlatformApplication::Arn

What example resource looks like?

In most basic form for GCM it can be set with resource as easy as:

ApplicationPlatform:
Type: Custom::SNSApplicationPlatform
Properties:
ServiceToken:
Fn::ImportValue: SNS::PlatformApplication::Arn
Platform: GCM
Name: some-cool-name
Attributes:
PlatformCredential: some-google-api-key
EventDeliveryFailure: !GetAtt SomeAlarmsTopic.TopicArn

You can also provide more attributes about delivery logging and you can subscribe to all failed deliveries to some SNS topic. All possible attributes can be found in AWS Docs.

ApplicationPlatformLogDeliveryRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- sns.amazonaws.com
Policies:
- PolicyName: AllowLogging
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- logs:PutMetricFilter
- logs:PutRetentionPolicy
Resource:
- "*"

ApplicationPlatform:
Type: Custom::SNSApplicationPlatform
Properties:
ServiceToken:
Fn::ImportValue: SNS::PlatformApplication::Arn
Platform: GCM
Name: some-cool-name
Attributes:
PlatformCredential: some-google-api-key
EventDeliveryFailure: !GetAtt SomeAlarmsTopic.TopicArn
SuccessFeedbackRoleArn: !GetAtt ApplicationPlatformLogDeliveryRole.Arn
FailureFeedbackRoleArn: !GetAtt ApplicationPlatformLogDeliveryRole.Arn
SuccessFeedbackSampleRate: 1

Return Values

There is only 1 return value from platform application custom resource which is PlatformApplicationArn. It can be referenced with !GetAtt ApplicationPlatform.PlatformApplicationArn or exported from your stack using snippet like:

Outputs:
ApplicationPlatformArn:
Value: !GetAtt ApplicationPlatform.PlatformApplicationArn
Export:
Name: MyApplicationPlatform::Arn

Conclusion

If you are CloudFormation user and you have to set up SNS Application Platform you can just use my custom resource lambda that can be found here: https://github.com/SodaDev/sns-platform-application instead of writing you own solution or scripts.

I hope it will make your life easier and your IaaC cleaner :)

--

--