CloudFormation - Create SNS subscription in disabled state - amazon-web-services

Is there a way to create an SNS subscription in the disabled state? This is for a lambda if that makes a difference.
Example:
MySubscription:
Type: AWS::SNS::Subscription
Properties:
Endpoint: arn:aws:lambda:region:account-id:function:mylambda
Protocol: lambda
TopicArn: arn:aws:sns:region:account-id:topic
Enabled: false # like this
Couldn't find anything like this in the AWS CloudFormation documentation

You can create a condition on the subscription creation.
First add a parameter:
"CreateSubscription": {
"Type": "String",
"AllowedValues": [
"true",
"false"
],
"Description": "Create subscription to sns"
}
after the 'parameters' section, create a 'conditions' section:
"Conditions" : {
"CreateSubscription" : {"Fn::Equals" : [{"Ref" : "CreateSubscription"}, "true"]}
}
add the condition to your subscription
"Subscription": {
"Type": "AWS::SNS::Subscription",
"Condition" : "CreateSubscription",
[...]
}
when you want to "activate" you subscription, you just have to change the parameter value updating the stack using the same template
Conditions section reference

There isn't a way with Cloudformation which conforms to your example. According to the documentation, AWS::SNS::Subscription does not have 'Enabled' as a setting.
Although, the documentation does state that the owner of the endpoint must confirm the subscription before Amazon SNS creates the subscription. So, in a sense, it's already disabled because it doesn't exist until you confirm it on the SNS topic.

Related

Issue with EventBridge rule for aws.events

I want to send to CloudWatch logs ALL the events sent to a custom event bus.
I created the custom event bus: my-event-bus
I created the CloudWatch log group
I created the event bus policy so everyone within my account can put an event into my-event-bus
I created a rule for that custom bus
This is the rule:
MyRuleForBus:
Type: AWS::Events::Rule
Properties:
Description: Testing rule
EventBusName:
Name: testing-rule-for-my-event-bus
EventPattern:
source:
- aws.events
State: ENABLED
Targets:
- Arn: arn:aws:logs:us-east-1:MY_ACCOUNT_ID:log-group:my-event-bus-log-group
Id: 'my-bus'
When I try to put an event
aws events put-events --entries file://put-events.json
I receive the following error
{
"FailedEntryCount": 1,
"Entries": [
{
"ErrorCode": "NotAuthorizedForSourceException",
"ErrorMessage": "Not authorized for the source."
}
]
}
This is the content of put-events.json
[
{
"Source": "aws.events",
"EventBusName": "my-event-bus",
"Detail": "{ \"key1\": \"value3\", \"key2\": \"value4\" }",
"Resources": [
"resource1",
"resource2"
],
"DetailType": "myDetailType"
}
]
But, if I change the source to other, for example, 'hello', in both, the rule and the event it works.
What am I doing wrong?
I want to make it work with aws.events so all the events sent to this bus end in CloudWatch (target)
aws.events belongs to AWS, not to you, thus you can't define it as source of your events. Only AWS can do it.
You need to use your own custom name for the source of your events, e.g. myapp.events.

How to add a redrive policy (dead-letter queue / DLQ) to a SNS subscription, with Ansible and AWS

In an Ansible script I have:
- name: Subscribe lambda to SNS topic example1
sns_topic:
name: "example1-{{env_name}}"
purge_subscriptions: no
subscriptions:
- endpoint: "arn:aws:lambda:{{ aws.region }}:{{ aws.account }}:function:{{repo_name}}-{{env_name}}"
protocol: "lambda"
It works, and the result is that my lambda is subscribed to my SNS topic.
Now, I would want to add a DLQ to this subscription.
I already have a SQS and I want to state it as my DLQ.
So I rewrite my code like this:
- name: Subscribe lambda to SNS topic example1
sns_topic:
name: "example1-{{env_name}}"
purge_subscriptions: no
subscriptions:
- endpoint: "arn:aws:lambda:{{ aws.region }}:{{ aws.account }}:function:{{repo_name}}-{{env_name}}"
protocol: "lambda"
redrive_policy:
dead_letter_target_arn: "arn:aws:{{ aws.region }}:{{ aws.account }}:dlq-for-example1"
This does not work and I didn't find anything in Ansible or by googling...
What am I doing wrong?
Looks like you are missing sqs between arn:aws:{{aws.region}} on the last line.
dead_letter_target_arn: "arn:aws:sqs:{{ aws.region }}:{{ aws.account }}:dlq-for-example1"
The problem is that the Subscription property that is embedded in the SNS Topic only has two properties: Endpoint and Protocol (See Subscription Property).
For more advanced settings, like RedrivePolicy, you need to use the stand-alone AWS::SNS::Subscription resource (See Subscription Resource).
Since AWS::SNS::Subscription is stand-alone, you must include the TopicArn that the Subscription is bound to. Also note that the RedrivePolicy is in Json format.
Here's a simple example of the Cloud Formation syntax from Redrive Syntax:
{
"Resources": {
"mySubscription": {
"Type" : "AWS::SNS::Subscription",
"Properties" : {
"Protocol": "sqs",
"Endpoint": "arn:aws:sqs:us-east-2:123456789012:MyEndpoint",
"TopicArn": "arn:aws:sns:us-east-2:123456789012:MyTopic",
"RedrivePolicy": {
"deadLetterTargetArn":
"arn:aws:sqs:us-east-2:123456789012:MyDeadLetterQueue"
}
}
}
}
}
But I don't know how Ansible makes these translations.

How to create and assign API Key to a created stage-API using serverless?

I want to create a secure APIG using serverless, in my current "s-fuction.json" I've already have:
"apiKeyRequired": true,
And in my "s-resources-cf.json" I already have:
"AWSApiKey": {
"Type": "AWS::ApiGateway::ApiKey",
"Properties" : {
"Description" : "ApiKey for secure the connections to the xxx API",
"Enabled" : true
}
}
It correctly creates all, a Lambda, an APIG for that lambda (including CORS) and the API Key, but I need to manually "assign" the key to the generated APIG-Stage, do you have any ideas on how could I do this automatically using serverless?
I've read the AWS documentation about the feature I want (and It seems it is possible) from here: AWS CloudFormation API Key
The documentation shows that it can be done by:
"ApiKey": {
"Type": "AWS::ApiGateway::ApiKey",
"DependsOn": ["TestAPIDeployment", "Test"],
"Properties": {
"Name": "TestApiKey",
"Description": "CloudFormation API Key V1",
"Enabled": "true",
"StageKeys": [{
"RestApiId": { "Ref": "RestApi" },
"StageName": "Test"
}]
}
}
But I don't know how add a reference to the APIG automatically created by serverless and how to wait for that APIG is created.
You can specify a list of API keys to be used by your service Rest API by adding an apiKeys array property to the provider object in serverless.yml. You'll also need to explicitly specify which endpoints are private and require one of the api keys to be included in the request by adding a private boolean property to the http event object you want to set as private. API Keys are created globally, so if you want to deploy your service to different stages make sure your API key contains a stage variable as defined below. When using API keys, you can optionally define usage plan quota and throttle, using usagePlan object.
Here's an example configuration for setting API keys for your service Rest API:
service: my-service
provider:
name: aws
apiKeys:
- myFirstKey
- ${opt:stage}-myFirstKey
- ${env:MY_API_KEY} # you can hide it in a serverless variable
usagePlan:
quota:
limit: 5000
offset: 2
period: MONTH
throttle:
burstLimit: 200
rateLimit: 100
functions:
hello:
events:
- http:
path: user/create
method: get
private: true
For more info read the following doc:
https://serverless.com/framework/docs/providers/aws/events/apigateway

Publish S3 Bucket Notification to SQS

I am trying to set up my S3 to notify my SQS Queue for a "PUT" Object Creation Event.
I am able to achieve this using CLI by:
aws --profile QA s3api put-bucket-notification --bucket <BUCKET_NAME> --notification-configuration '{ "QueueConfiguration": { "Id": "<EVENT ID>", "Event": "s3:ObjectCreated:Put", "Queue": "<QUEUE ARN>" } }'
Also able to do the same using Java:
NotificationConfiguration notificationConfiguration = new QueueConfiguration(queueArn, EnumSet.of(S3Event.ObjectCreatedByPut));
BucketNotificationConfiguration bucketNotificationConfiguration = new BucketNotificationConfiguration("DropShipInboundQueueDelivery", notificationConfiguration);
client.setBucketNotificationConfiguration(bucketName, bucketNotificationConfiguration)
However when I tried to something similar using CloudFormation template, I cannot find any way to trigger a notification to SQS. The only option I see that works and is documented is to trigger notification to SNS.
I have referred the Cloud Formation Documentation:
I looked at the AWS::S3::Bucket docs to look at the outer syntax. I saw NotificationConfiguration which I need to set
However the Notification Configuration can only contain a list of TopicConfigurations with was the old constructor in JDK before QueueConfiguration was supported
I tried doing something like this:
"NotificationConfiguration" :{
"QueueConfiguration": {
"Id": "DropshipInboundEventNotification",
"Event": "s3:ObjectCreated:Put",
"Queue": "arn:aws:sqs:*:*:Dropship-Inbound-qa"
}
},
But this as expected threw an error: "Encountered unsupported property QueueConfiguration" from amazon.
Looked at this API documentation
I would like to know if someone has been able to do this using CloudFormation Templates as thats how I am maintaining all the other AWS resources and do not want to do anything special for this particular feature.
Any help is appreciated.
There is no need "Id" in Cloudformation Template ( You can check from QueueConfiguration Doc ) and your second mistake, that is not "QueueConfiguration", it's "QueueConfigurations". Because of that you get an error that says "Encountered unsupported property QueueConfiguration"
It must be something like that.
"S3Bucket":{
"Type" : "AWS::S3::Bucket",
"Properties" : {
"AccessControl" : String,
"BucketName" : String,
"CorsConfiguration" : CORS Configuration,
"LifecycleConfiguration" : Lifecycle Configuration,
"LoggingConfiguration" : Logging Configuration,
"NotificationConfiguration" :
{ "QueueConfigurations" : [ {
"Event" : "s3:ObjectCreated:Put",
"Queue" : "arn:YOURQUEUEARN"
} ] },
"Tags" : [ Resource Tag, ... ],
"VersioningConfiguration" : Versioning Configuration,
"WebsiteConfiguration" : Website Configuration Type
}
}
While you are reading cloudformation template documents, you must be careful about "Required:" sections. If it is not required, you don't need to fill it, just remove that line from your template if you don't use it( Like S3 Tags ).
Other Docs about it:
S3BucketDocs
NotificationConfigurationDocs

create event subscriptions in RDS with CloudFormation

Does CloudFormation support or have the ability to create DB event subscriptions(RDS)?
I failed to find any reference in AWS document...
Thanks
The latest version of CloudFormation, at the time of this writing, actually supports performing this by creating a "AWS::RDS::EventSubscription" resource in your stack.
"myEventSubscription": {
"Type": "AWS::RDS::EventSubscription",
"Properties": {
"EventCategories": ["configuration change", "failure", "deletion"],
"SnsTopicArn": "arn:aws:sns:us-west-2:123456789012:example-topic",
"SourceIds": ["db-instance-1", { "Ref" : "myDBInstance" }],
"SourceType":"db-instance",
"Enabled" : false
}
}