是否可以使用Cloudformation模板创建SNS平台应用程序?
支持aws-cli
,http://docs.aws.amazon.com/cli/latest/reference/sns/create-platform-application.html。但是没有关于对Cloudformation做同样的事情的信息,它是否得到支持(http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sns-topic.html)?
答案 0 :(得分:3)
否即可。在AWS中使用CloudFormation创建SNS平台应用程序
。我面临同样的问题。在AWS Could Formation docs中,今天只有AWS::SNS::Subscription
,AWS::SNS::Topic
和AWS::SNS::TopicPolicy
。它们都不允许定义平台应用程序。
除非可以在另一个AWS::
服务下声明它,否则今天不可能。希望很快就能有这个功能。
解决方案:
•由于创建/更新应用程序端点是一个罕见的“事件”,每年一次,我将手动:(创建它们。
•awscli
和aws-sdk
似乎支持平台应用程序的创建,但它会增加额外的依赖性或开发
答案 1 :(得分:0)
值得添加一些额外的工作来获得自动化和可重复性的好处。
我使用 AWS::CloudFormation::CustomResource
和 Lambda 函数来完成这项工作。
将此添加到您的 CloudFormation 定义中。
"MyPlatformApplication": {
Type: "AWS::CloudFormation::CustomResource",
DependsOn: [ "PlatformApplicationProvisionLambdaFunction" ],
Properties: {
ServiceToken: { "Fn::GetAtt", "PlatformApplicationProvisionLambdaFunction.Arn" },
Name: "MyPlatformApplication",
Platform: "GCM",
PlatformCredential: "<Your FCM ServerKey>",
},
},
并使用您的首选策略定义 Lambda 函数 PlatformApplicationProvisionLambdaFunction
。对我来说,我使用无服务器框架,因此我可以将上述自定义资源与 Lambda 函数放在同一个存储库中,并一次性部署所有这些资源。
这是 Typescript 中的 Lambda 代码
import {
CreatePlatformApplicationCommand,
DeletePlatformApplicationCommand,
SetPlatformApplicationAttributesCommand,
SNSClient,
} from '@aws-sdk/client-sns';
import {
CloudFormationCustomResourceCreateEvent,
CloudFormationCustomResourceDeleteEvent,
CloudFormationCustomResourceEvent,
CloudFormationCustomResourceUpdateEvent,
Context,
} from 'aws-lambda';
import response from 'cfn-response';
import middy from '@middy/core';
import middyJsonBodyParser from '@middy/http-json-body-parser';
const snsClient = new SNSClient({});
const parseInput = (event: CloudFormationCustomResourceEvent) => {
const input = {
Name: event.ResourceProperties.Name,
Platform: event.ResourceProperties.Platform,
PlatformCredential: event.ResourceProperties.PlatformCredential,
};
if (input.Name === undefined) {
throw new Error('Missing parameter: Name');
}
if (input.Platform === undefined) {
throw new Error('Missing parameter: Platform');
}
if (input.PlatformCredential === undefined) {
throw new Error('Missing parameter: PlatformCredential');
}
return input;
};
const processCreate = async (event: CloudFormationCustomResourceCreateEvent, context: Context) => {
const input = parseInput(event);
const result = await snsClient.send(
new CreatePlatformApplicationCommand({
Name: input.Name,
Platform: input.Platform,
Attributes: {
PlatformCredential: input.PlatformCredential,
},
}),
);
response.send(event, context, 'SUCCESS', {
Arn: result.PlatformApplicationArn,
});
};
const processUpdate = async (event: CloudFormationCustomResourceUpdateEvent, context: Context) => {
const input = parseInput(event);
const arn = `arn:aws:sns:${process.env.REGION}:${process.env.ACCOUNT_ID}:app/${input.Platform}/${input.Name}`;
await snsClient.send(
new SetPlatformApplicationAttributesCommand({
PlatformApplicationArn: arn,
Attributes: {
PlatformCredential: input.PlatformCredential,
},
}),
);
response.send(event, context, 'SUCCESS', {
Arn: arn,
});
};
const processDelete = async (event: CloudFormationCustomResourceDeleteEvent, context: Context) => {
const input = parseInput(event);
const arn = `arn:aws:sns:${process.env.REGION}:${process.env.ACCOUNT_ID}:app/${input.Platform}/${input.Name}`;
await snsClient.send(
new DeletePlatformApplicationCommand({
PlatformApplicationArn: arn,
}),
);
response.send(event, context, 'SUCCESS', {
Arn: arn,
});
};
const handler = async (event: CloudFormationCustomResourceEvent, context: Context) => {
try {
if (event.RequestType === 'Create') {
await processCreate(event, context);
} else if (event.RequestType === 'Update') {
await processUpdate(event, context);
} else {
await processDelete(event, context);
}
} catch (err) {
if (err instanceof Error) {
response.send(event, context, 'FAILED', { message: err.message });
} else {
response.send(event, context, 'FAILED', err);
}
}
};
export const main = middy(handler).use(middyJsonBodyParser());