In My Cloudformation template I need to Add SNS Topic to get notifications for Scan and Install Patches.

0

https://aws.amazon.com/blogs/mt/scheduling-centralized-multi-account-multi-region-patching-aws-systems-manager-automation/ As per this blog i have created Cloudformation Templates for Patching and on this template how i need to add SNS topic for getting notifications for Scan and Install Patches, kindly please help me on this

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation template to create a scheduled multi-account and multi-Region patching operation using Amazon EventBridge, AWS Lambda, and AWS Systems Manager Automation.
Parameters:
  EventBridgeRuleSchedule:
    Type: String
    Description: >-
      The cron or rate expression to use for the EventBridge rule. For example: cron(0 02 ? * TUE *). Important: The time zone used is UTC. For more information, see https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html.
  ExecutionRoleName:
    Type: String
    Default: AWS-SystemsManager-AutomationExecutionRole
    Description: >-
      The Automation execution role to be assumed in target accounts during multi-account and multi-Region Automation patching operations.
  ExistingAutomationAdministrationRole:
    Type: String
    Description: >-
      (Optional) The IAM role ARN of an existing Automation Administration role which has permissions to invoke multi-account and multi-Region Automation workflows.
  MaximumConcurrency:
    Type: String
    Default: 10%
    Description: >-
      Specify the number or percentage of targets on which to execute the task at the same time. You can specify a number, such as 10, or a percentage, such as 10%. The default value is 10%.
  MaximumErrors:
    Type: String
    Default: 10%
    Description: >-
      The number of errors that are allowed before the system stops initiating the automation on additional targets. You can specify either an absolute number of errors, for example 10, or a percentage of the target set, for example 10%. The default value is 10%.
  RunPatchBaselineOperation:
    Type: String
    Default: Scan
    AllowedValues:
      - Scan
      - Install
      - Scan and Install
    Description: >-
      (Required) The update or configuration to perform on the instance. The Scan operation checks if patches specified in the patch baseline are installed on the instance. The Install operation installs patches missing from the baseline.
  RunPatchBaselineRebootOption:
    Type: String
    Default: NoReboot
    AllowedValues:
      - RebootIfNeeded
      - NoReboot
    Description: >-
      (Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.
  RunPatchBaselineInstallOverrideList:
    Type: String
    Default: ''
    AllowedPattern: '(^$)|^https://.+$|^s3://([^/]+)/(.*?([^/]+))$'
    Description: >-
      (Optional) An https URL or an Amazon S3 path-style URL to the list of patches to be installed. This patch installation list overrides the patches specified by the default patch baseline.
  ResourceGroupName:
    Type: String
    Description: >-
      Enter a resource group that includes the resources you want to target. Important: The Resource Group name is case sensitive.
  TargetAccounts:
    Type: String
    Description: >-
      Comma separated list of AWS Account Ids for the target account(s).
  TargetLocationMaxConcurrency:
    Type: String
    Default: '1'
    Description: >-
      Specify the number or percentage of locations (account-Region pairs) on which to execute the task at the same time. You can specify a number, such as 10, or a percentage, such as 10%. The default value is 1.
  TargetLocationMaxErrors:
    Type: String
    Default: '1'
    Description: >-
      Specify an error threshold which will stop the task after the task fails on a specific number or percentage of locations. You can specify either an absolute number of errors, for example 10, or a percentage of the locations, for example 10%. The default value is 1.
  TargetRegionIds:
    Type: String
    Description: >-
      Comma separated list of AWS Regions to target. For example: us-east-1,ap-south-1.
Conditions:
  CreateAutomationAdministrationRoleCondition:
    Fn::Equals:
      - Ref: ExistingAutomationAdministrationRole
      - ''
Resources:
  EventBridgeRule:
    Type: AWS::Events::Rule
    Properties:
      Description: EventBridge rule created for scheduled multi-account and multi-Region Automation patching using AWS Lambda and AWS Systems Manager Automation
      Name: Schedule-Trigger-for-Lambda-MultiAccountPatchingBlog
      ScheduleExpression:
        Ref: EventBridgeRuleSchedule
      State: ENABLED
      Targets:
        - Arn:
            Fn::GetAtt:
              - MultiAccountPatchingBlogLambdaFunction
              - Arn
          Id: MultiAccountPatchingBlog
  PermissionForEventsToInvokeLambda:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName:
        Ref: MultiAccountPatchingBlogLambdaFunction
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn:
        Fn::GetAtt:
          - EventBridgeRule
          - Arn
  AWSLambdaSSMMultiAccountPatchingBlogRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWS-Lambda-SSM-MultiAccountPatchingBlogRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action: sts:AssumeRole
      Path: "/"
      Policies:
        - PolicyName: AWSLambdaSSMMultiAccountPatchingBlogPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - ssm:StartAutomationExecution
                Resource:
                  - Fn::Sub: arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${AutomationDocumentMamrRunPatchBaseline}:$DEFAULT
              - Action: iam:PassRole
                Resource:
                  Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:role/AWS-SystemsManager-AutomationAdministrationRole
                Effect: Allow
              - Action: logs:CreateLogGroup
                Resource:
                  Fn::Sub: arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:*
                Effect: Allow
              - Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource:
                  Fn::Sub: arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/MultiAccountPatchingBlog:*
                Effect: Allow
  MultiAccountPatchingBlogLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: |
          import boto3
          import os
          import string
          import uuid

          client = boto3.client('ssm')

          def handler(event,context):
              TargetAccounts=os.environ['TargetAccounts']
              b = str(TargetAccounts)
              TargetAccountsArray = b.split(",")
              TargetRegionIds=os.environ['TargetRegionIds']
              b = str(TargetRegionIds)
              TargetRegionIdsArray = b.split(",")
              RunPatchBaselineOperation=os.environ['RunPatchBaselineOperation']
              RunPatchBaselineRebootOption=os.environ['RunPatchBaselineRebootOption']
              RunPatchBaselineInstallOverrideList=os.environ['RunPatchBaselineInstallOverrideList']
              ResourceGroupName=os.environ['ResourceGroupName']
              MaximumConcurrency=os.environ['MaximumConcurrency']
              MaximumErrors=os.environ['MaximumErrors']
              TargetLocationMaxConcurrency=os.environ['TargetLocationMaxConcurrency']
              TargetLocationMaxErrors=os.environ['TargetLocationMaxErrors']
              ExecutionRoleName=os.environ['ExecutionRoleName']
              MasterAccountID=os.environ['MasterAccountID']
              AutomationDocumentMamrRunPatchBaseline=os.environ['AutomationDocumentMamrRunPatchBaseline']
              
              if len(RunPatchBaselineInstallOverrideList) > 0:
                  response = client.start_automation_execution(
                  DocumentName=f'{AutomationDocumentMamrRunPatchBaseline}',
                  
                  Parameters={
                      'AutomationAssumeRole':[f'arn:aws:iam::{MasterAccountID}:role/AWS-SystemsManager-AutomationAdministrationRole'] ,
                      'Operation' : [f'{RunPatchBaselineOperation}'] ,
                      'RebootOption' : [f'{RunPatchBaselineRebootOption}'] ,
                      'InstallOverrideList' : [f'{RunPatchBaselineInstallOverrideList}'] ,
                      'SnapshotId' : [str(uuid.uuid4())]
                  },
                  TargetLocations=[
                      {
                          'Accounts': TargetAccountsArray,
                          'Regions': TargetRegionIdsArray,
                          'TargetLocationMaxConcurrency': f'{TargetLocationMaxConcurrency}',
                          'TargetLocationMaxErrors': f'{TargetLocationMaxErrors}',
                          'ExecutionRoleName': f'{ExecutionRoleName}'
                      }
                  ]
              )
              else:
                  response = client.start_automation_execution(
                  DocumentName=f'{AutomationDocumentMamrRunPatchBaseline}',
                  
                  Parameters={
                      'AutomationAssumeRole':[f'arn:aws:iam::{MasterAccountID}:role/AWS-SystemsManager-AutomationAdministrationRole'] ,
                      'Operation' : [f'{RunPatchBaselineOperation}'] ,
                      'RebootOption' : [f'{RunPatchBaselineRebootOption}'] ,
                      'SnapshotId' : [str(uuid.uuid4())]
                  },
                  TargetLocations=[
                      {
                          'Accounts': TargetAccountsArray,
                          'Regions': TargetRegionIdsArray,
                          'TargetLocationMaxConcurrency': f'{TargetLocationMaxConcurrency}',
                          'TargetLocationMaxErrors': f'{TargetLocationMaxErrors}',
                          'ExecutionRoleName': f'{ExecutionRoleName}'
                      }
                  ]
              )
              print(response)

      Environment: 
            Variables:
                TargetAccounts: !Ref TargetAccounts
                TargetRegionIds: !Ref TargetRegionIds
                RunPatchBaselineOperation: !Ref RunPatchBaselineOperation
                RunPatchBaselineRebootOption: !Ref RunPatchBaselineRebootOption
                RunPatchBaselineInstallOverrideList: !Ref RunPatchBaselineInstallOverrideList
                ResourceGroupName: !Ref ResourceGroupName
                MaximumConcurrency: !Ref MaximumConcurrency
                MaximumErrors: !Ref MaximumErrors
                TargetLocationMaxConcurrency: !Ref TargetLocationMaxConcurrency
                TargetLocationMaxErrors: !Ref TargetLocationMaxErrors
                ExecutionRoleName: !Ref ExecutionRoleName
                MasterAccountID: !Sub ${AWS::AccountId}
                AutomationDocumentMamrRunPatchBaseline: !Ref AutomationDocumentMamrRunPatchBaseline
      FunctionName: MultiAccountPatchingBlog
      Handler: index.handler
      Role: !GetAtt AWSLambdaSSMMultiAccountPatchingBlogRole.Arn 
      Runtime: python3.7    
    
  AutomationAdministrationServiceRole:
    Type: AWS::IAM::Role
    Condition: CreateAutomationAdministrationRoleCondition
    Properties:
      RoleName: AWS-SystemsManager-AutomationAdministrationRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ssm.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: "/"
      Policies:
        - PolicyName: AssumeRole-AWSSystemsManagerAutomationExecutionRole
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - sts:AssumeRole
                Resource:
                  Fn::Sub: arn:${AWS::Partition}:iam::*:role/AWS-SystemsManager-AutomationExecutionRole
              - Effect: Allow
                Action:
                  - organizations:ListAccountsForParent
                Resource:
                  - "*"
  AutomationDocumentMamrRunPatchBaseline:
    Type: AWS::SSM::Document
    Properties: 
      Name: Automation-RunPatchBaseline
      DocumentType: Automation
      Content:
        description: >-
          **Description**
          
          This document runs the Command document ```AWS-RunPatchBaseline``` on the specified instances.
        schemaVersion: '0.3'
        assumeRole: '{{ AutomationAssumeRole }}'
        parameters:
          AutomationAssumeRole: 
            type: String
            description: The ARN of the Automation service role to assume.
          Operation:
            type: String
            default: Scan
            description: >-
              (Required) The update or configuration to perform on the instance. The
              system checks if patches specified in the patch baseline are installed on
              the instance. The install operation installs patches missing from the
              baseline.
          RebootOption:
            type: String
            default: RebootIfNeeded
            description: >-
              (Optional) Reboot behavior after a patch Install operation. If you choose
              NoReboot and patches are installed, the instance is marked as non-compliant 
              until a subsequent reboot and scan.
          InstallOverrideList:
            type: String
            default: ""
            description: >-
              (Optional) An https URL or an Amazon S3 path-style URL to the list of patches to be installed. This patch installation list overrides the patches specified by the default patch baseline.
          SnapshotId:
            type: String
            default: ""
            description: >-
              (Optional) The snapshot ID to use to retrieve a patch baseline snapshot.
        mainSteps:
          - name: runPatchBaselineScan
            action: 'aws:runCommand'
            timeoutSeconds: 7200
            onFailure: Continue
            inputs:
              DocumentName: AWS-RunPatchBaseline
              Targets:
              - Key: 'resource-groups:Name'
                Values:
                  - !Ref ResourceGroupName
              Parameters:
                Operation: 'Scan'
                SnapshotId: '{{ SnapshotId }}'
              MaxConcurrency: !Ref MaximumConcurrency
              MaxErrors: !Ref MaximumErrors
            description: >-
              This command runs the Command document ```AWS-RunPa

1 Answer
0

Hi,¨

You have here a code snippet for adding a SNS notification via YAML: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-sns.html

MySNSTopic:
  Type: AWS::SNS::Topic
  Properties:
    Subscription:
    - Endpoint: "add valid email address"
      Protocol: email

Best,

Didier

profile pictureAWS
EXPERT
answered 4 months ago
  • I have a question here the mentioned code snippet does not say anything about Lambda, the above snippet create the SNS Topic and it does not trigger any email to an email address which i have configured kindly suggest a solution and attach them to the original code if possible.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions