Subscribing to AWS Security Hub announcements using CloudFormation

The AWS Security Hub team launched announcements for Security Hub features via an SNS topic in August 2022. The team now publishes announcements to stay up to date with feature releases. To receive these announcements all you need to do is subscribe to the AWS Security Hub SNS topic in your preferred region.

The SNS topic ARN is different for most regions, and to help subscribe to the correct topic AWS publish a full list of Region specific topics. To make this a little easier I have codified this subscription into a CloudFormation template. This template uses a mapping resource to use the correct Topic ARN for the Region the stack is deployed.

We can use the intrinsic function Fn:FindInMap and the Pseudo parameter AWS::Region to pragmatically subscribe to the correct Topic when the Stack is launched in CloudFormation.

Breaking down the CloudFormation template, we have three parts

Email address parameter

Here we define the parameter for the email address we wish to subscribe

Parameters:
  EmailAddress:
    Type: String
    Description: >
      The email adddress to subscribe to notifications.
      You will need to Confirm the subscription. Amazon SNS will send a subscription confirmation message to the email you provided.
Regional Topic mapping

Here we need to define the Region Topic ARNs that can be subscribed to. The first level of the Map is the Region and the second level is the SecurityHubAnnoucements topic ARN. These ARNs are listed in the documentation.

Mappings:
  RegionMap:
    us-east-2:
      SecurityHubAnnouncements: "arn:aws:sns:us-east-2:291342846459:SecurityHubAnnouncements"
    us-east-1:
      SecurityHubAnnouncements: "arn:aws:sns:us-east-1:088139225913:SecurityHubAnnouncements"
    us-west-1:
      SecurityHubAnnouncements: "arn:aws:sns:us-west-1:137690824926:SecurityHubAnnouncements"
    us-west-2:
      SecurityHubAnnouncements: "arn:aws:sns:us-west-2:393883065485:SecurityHubAnnouncements"
    af-south-1:
      SecurityHubAnnouncements: "arn:aws:sns:af-south-1:463142546776:SecurityHubAnnouncements"
    ap-east-1:
      SecurityHubAnnouncements: "arn:aws:sns:ap-east-1:464812404305:SecurityHubAnnouncements"
    ap-southeast-3:
      SecurityHubAnnouncements: "arn:aws:sns:ap-southeast-3:627843640627:SecurityHubAnnouncements"
    ap-south-1:
      SecurityHubAnnouncements: "arn:aws:sns:ap-south-1:707356269775:SecurityHubAnnouncements"
    ap-northeast-3:
      SecurityHubAnnouncements: "arn:aws:sns:ap-northeast-3:633550238216:SecurityHubAnnouncements"
    ap-northeast-2:
      SecurityHubAnnouncements: "arn:aws:sns:ap-northeast-2:374299265323:SecurityHubAnnouncements"
    ap-southeast-1:
      SecurityHubAnnouncements: "arn:aws:sns:ap-southeast-1:512267288502:SecurityHubAnnouncements"
    ap-southeast-2:
      SecurityHubAnnouncements: "arn:aws:sns:ap-southeast-2:475730049140:SecurityHubAnnouncements"
    ap-northeast-1:
      SecurityHubAnnouncements: "arn:aws:sns:ap-northeast-1:592469075483:SecurityHubAnnouncements"
    ca-central-1:
      SecurityHubAnnouncements: "arn:aws:sns:ca-central-1:137749997395:SecurityHubAnnouncements"
    cn-north-1:
      SecurityHubAnnouncements: "arn:aws-cn:sns:cn-north-1:672341567257:SecurityHubAnnouncements"
    cn-northwest-1:
      SecurityHubAnnouncements: "arn:aws-cn:sns:cn-northwest-1:672534482217:SecurityHubAnnouncements"
    eu-central-1:
      SecurityHubAnnouncements: "arn:aws:sns:eu-central-1:871975303681:SecurityHubAnnouncements"
    eu-west-1:
      SecurityHubAnnouncements: "arn:aws:sns:eu-west-1:705756202095:SecurityHubAnnouncements"
    eu-west-2:
      SecurityHubAnnouncements: "arn:aws:sns:eu-west-2:883600840440:SecurityHubAnnouncements"
    eu-south-1:
      SecurityHubAnnouncements: "arn:aws:sns:eu-south-1:151363035580:SecurityHubAnnouncements"
    eu-west-3:
      SecurityHubAnnouncements: "arn:aws:sns:eu-west-3:313420042571:SecurityHubAnnouncements"
    eu-north-1:
      SecurityHubAnnouncements: "arn:aws:sns:eu-north-1:191971010772:SecurityHubAnnouncements"
    me-south-1:
      SecurityHubAnnouncements: "arn:aws:sns:me-south-1:585146626860:SecurityHubAnnouncements"
    sa-east-1:
      SecurityHubAnnouncements: "arn:aws:sns:sa-east-1:359811883282:SecurityHubAnnouncements"
    us-gov-east-1:
      SecurityHubAnnouncements: "arn:aws-us-gov:sns:us-gov-east-1:239368469855:SecurityHubAnnouncements"
    us-gov-west-1:
      SecurityHubAnnouncements: "arn:aws-us-gov:sns:us-gov-west-1:239334163374:SecurityHubAnnouncements"
SNS Subscription resource

Finally, pulling all the pieces together we create a AWS::SNS::Subscription resource which references the Email parameter mention earlier and using the FindInMap intrinsic function, uses the Topic ARN for the Region where the Stack is being executed using the AWS::Region pseudo parameter.

Resources:
  SecurityHubSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      Endpoint: !Ref EmailAddress
      Protocol: email
      TopicArn: !FindInMap
        - RegionMap
        - !Ref "AWS::Region"
        - SecurityHubAnnouncements
Launching the Stack

Now we have a full CloudFormation template, you can upload this template to an S3 bucket of your choosing and launch a Stack in your preferred Region. Once the stack launches, you should get a confirmation email from AWS SES which you need to confirm the subscription.

Once you Confirm the Subscription you will receive announcements to your nominated email address.

Feel free to download a copy of my template from my Github Repository

Rich Carpenter

Richard is an Information Security Expert, focussed on the implementation and architecture of Digital Transformation and Public Cloud adoption at forward thinking organisations.