SNS Subscription Wants a String - amazon-web-services

I'm trying to update my SNS subscription with a second endpoint however I get this error
"Value of property Endpoint must be of type String"
Here is my YAML. Is there a different way to add two endpoints to the one subscription? Thanks
ConnectorSubscription:
Type: AWS::SNS::Subscription
Properties:
Endpoint:
- "https://my-endpoint-name-1"
- "https://my-endpoint-name-2"
Protocol: "https"
TopicArn: !Ref ConnectorTopic

An HTTPS subscription can only have a single endpoint. You will need to create multiple subscriptions.
This is a very useful design. For example, let's say that one endpoint is working well while another is non-responsive. Amazon SNS will re-try the non-responsive endpoint independently to other subscriptions.

Related

How to use email dynamic list to SNS Topic Subscription in AWS CloudFormation?

My templaste is (for one emeil):
Parameters:
MailAlarmsSNS:
Type: String
Default: mymail#company.com
MessagesInErrorTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: foo
DisplayName: This topic is used to send an email
Subscription:
- Endpoint: !Ref MailAlarmsSNS
Protocol: email
I want use a dynamic list input (comma separated)?
You can only do that using custom resource or a macro that you would have to develop yourself in the form of lambda functions.
As stated by #Marcin, you typically need to use a custom resource or macro for that. This repository gives you complete code using the custom resource to add multiple endpoints.
You can give multiple endpoints in a single SNS Topic like below:

AWS API Gateway integration with AWS Event Bridge(Cloudwatch Events) in Cloudformation Script

Original Requirement:
Create a route/path on AWS Api Gateway which connects API Gateway directly to AWS Event Bridge (Cloudwatch Events) and puts/pushes event on an event bus of it.
Was able to create it and executes just fine when done from AWS Console.
Actual Problem:
When writing the AWS Cloudformation script for this API Gateway, it looks like this:
EventsPostMethod:
Type: AWS::ApiGateway::Method
Properties:
ResourceId:
Ref: EventsResource
RestApiId:
Ref: RestAPI
HttpMethod: POST
AuthorizationType: NONE
Integration:
Type: AWS
IntegrationHttpMethod: POST
Uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:cloudwatchEvents:action/PutEvents
RequestParameters:
integration.request.header.X-Amz-Target: "'AWSEvents.PutEvents'"
RequestTemplate:
some-script-here...
Notice the Uri value:
"arn:aws:apigateway:${AWS::Region}:cloudwatchEvents:action/PutEvents"
arn:aws:apigateway:{region}:{subdomain.service|service}:path|action/{service_api}
According to AWS Docs the value of uri should be following:
For AWS or AWS_PROXY integrations, the URI is of the form arn:aws:apigateway:{region}:{subdomain.service|service}:path|action/{service_api}. Here, {Region} is the API Gateway region (e.g., us-east-1); {service} is the name of the integrated AWS service (e.g., s3); and {subdomain} is a designated subdomain supported by certain AWS service for fast host-name lookup. action can be used for an AWS service action-based API, using an Action={name}&{p1}={v1}&p2={v2}... query string. The ensuing {service_api} refers to a supported action {name} plus any required input parameters. Alternatively, path can be used for an AWS service path-based API. The ensuing service_api refers to the path to an AWS service resource, including the region of the integrated AWS service, if applicable. For example, for integration with the S3 API of GetObject, the uri can be either arn:aws:apigateway:us-west-2:s3:action/GetObject&Bucket={bucket}&Key={key} or arn:aws:apigateway:us-west-2:s3:path/{bucket}/{key}
You must have noticed that I replaced the service with cloudwatchEvents in the above mentioned uri.
Now, error Given by AWS Cloudformation Console during Publish of API Gateway:
AWS Service of type cloudwatchEvents not supported (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: 07bae22c-d198-4595-8de9-6ea23763eff5; Proxy: null)
Now I have tried replacing service with
cloudwatch
eventBridge
cloudwatchEvent
event-bus
This is the real problem. What should I place in service in uri so that it accepts ?
Based on the comments,
The URI should be something like below for events:
arn:aws:apigateway:${AWS::Region}:events:action/PutEvents

How to get ARN for SNS Topic created using cloud formation?

I have created SNS using cloud formation like this -
MYSNS:
Type: AWS::SNS::Topic
Properties:
DisplayName: "MYSNS"
TopicName: "MYSNS"
Now, I want to publish message to this topic using Java but
snsClient.publish(snsARN, snsEvent);
sns client requires ARN to publish the event. How I can get SNS Topic ARN?
Edit 1: Post deployment we can get the ARN, but don't want this way.
Ex - We can get SQS url by it's Name using SQS Client like this -
sqsClient.getQueueUrl(dlqName).getQueueUrl(); I am looking for similar way in case of SNS.
You can construct the ARN yourself:
arn:aws:sns:<region>:<account>:MYSNS
You can try this in cloudformation template to get the created SNS's ARN
!Ref MYSNS

Can AWS CloudFormation templates for AWS Inspector add an SNS Topic

I've created some CloudFormation templates to deploy Inspector Templates/Targets and associated Lambda functions that parse the outputs and deliver findings to Slack. Is it possible to include in the CF template for Inspector an SNS Topic association as is done when creating a template in the Inspector portal?
It is not an available parameter of AWS::Inspector::AssessmentTemplate. Is this something I will just have to add manually via the portal?
I see the SNS option is available only in the UI and CLI/API, I guess the UI/CLI creates Cloudwatch Events rule for you in the background, you create your own rule using AWS::Events::Rule
Reference: Event Patterns
EventRule:
Type: "AWS::Events::Rule"
Properties:
Description: "EventRule"
EventPattern:
source:
- "aws.inspector"
detail-type:
- "AWS API Call via CloudTrail"
resources:
- arn:aws:inspector:us-west-2:123456789012:target/0-nvgVhaxX/template/0-7sbz2Kz0
detail:
eventSource:
- "inspector.amazonaws.com"
eventName:
- "ASSESSMENT_RUN_COMPLETED"
State: "ENABLED"
Targets:
- arn:aws:sns:us-west-2:123456789012:exampletopic
This is how I did it. I used the cloud formation template to create the assessment target, assessment resource group, and assessment template. Also, included a cloudwatch event rule to trigger assessment runs on a weekly basis.
As of today, there is no support for adding an SNS Topic through the Inspector Assessment template cloud formation resource, I went through the boto3 API for event subscription. Refer the API here: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/inspector.html#Inspector.Client.subscribe_to_event
If you refer the above API Doc you will be able to develop a small python lambda function to subscribe your inspector assessment template to the SNS topic. Then call that lambda function using a custom resource as follows in the same template where the assessment template is provisioned or defined.
Custom resource would look something like below:
SubscribeToEvent:
Type: "Custom::<whatever_name>"
Version: "1.0"
Properties:
ServiceToken: !GetAtt <Lambda function logical name>.Arn
AssessmentTemplateArn: !GetAtt <Assessment template logical name>.Arn
topicArn: !Sub arn:aws:sns:${AWS::Region}:${account number}:<Nameofthetopic>
If you are trying to refer a cross-account topic or a topic which exist in another account, in that case, you need to update the topic policy to grant publish topic permissions to AWS Inspector Account. To find the AWS Account numbers refer here : https://docs.aws.amazon.com/inspector/latest/userguide/inspector_assessments.html#sns-topic

ansible sns - why is subscriber optional

When I am subscribing a lambda function to an SNS topic through either the aws console or aws cli there is a column shown in the subscription information called "subscriber". It does contain my account id.
I don't seem to be able to control this field through the cli or console however I can through ansible:
---
- name: set up topic and subscribe lambda
sns_topic:
name: "topic_name"
state: present
display_name: "Display Name"
subscriptions:
- endpoint: "arn:aws:lambda:ap-southeast-2:123456789:function:functionName"
protocol: "lambda"
subscriber: 123456789
The subscriber field is optional, however SNS messages do not seem to reach lambda without it.
What is this field for?
Can I subscribe Lambdas in other accounts to my SNS topic?
How can I effect change in this field with AWS CLI?
Why is it optional in Ansible 2.4
Couldn't find reference to ghost field i.e. subscriber.
Maybe it was supported in older sdk/api and now has been dropped.
Reseach:
I don't see subscriber field in the console when subscribing lambda. Image below
Even through CLI, there is no such field
Link for SNS Subscribe command through CLI documentation.
[Extra Research]: Even the java sdk asks for only three parameters in order to subscribe
subscribe(String topicArn, String protocol, String endpoint)
Java doc link