能否在AWS Inspector的CloudFormation模板中关联SNS Topic?
如何在CloudFormation中自动关联Inspector评估模板与SNS Topic
嘿,你提的这个问题挺常见的——确实AWS::Inspector::AssessmentTemplate这个CloudFormation资源本身没有直接配置SNS订阅的参数,但绝对不用手动去控制台操作!我给你两个靠谱的自动化方案,帮你把SNS关联整合到CFN模板里:
方案1:用CloudFormation自定义资源(首推)
这个方案能让你在部署CFN栈时自动完成SNS关联,销毁栈时还能自动解除订阅,完全实现端到端自动化。
具体步骤:
- 先定义你的SNS Topic
在CFN模板里先把要关联的SNS Topic资源写好:
Resources: InspectorAlertSNSTopic: Type: AWS::SNS::Topic Properties: DisplayName: InspectorAssessmentAlerts
- 写个自定义Lambda函数处理API调用
Inspector的控制台操作其实背后是调用了SubscribeToEvent和UnsubscribeFromEventAPI,我们用Lambda来封装这些调用,让CloudFormation能触发它:
InspectorSNSSubscriberLambda: Type: AWS::Lambda::Function Properties: Runtime: python3.11 Handler: index.lambda_handler Role: !GetAtt InspectorSNSSubscriberLambdaRole.Arn Code: ZipFile: | import boto3 import cfnresponse inspector = boto3.client('inspector') def lambda_handler(event, context): try: template_arn = event['ResourceProperties']['AssessmentTemplateArn'] topic_arn = event['ResourceProperties']['SNSTopicArn'] event_type = event['ResourceProperties']['EventType'] if event['RequestType'] in ['Create', 'Update']: # 关联SNS和评估模板 inspector.subscribe_to_event( resourceArn=template_arn, event=event_type, topicArn=topic_arn ) cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) elif event['RequestType'] == 'Delete': # 栈销毁时取消订阅 inspector.unsubscribe_from_event( resourceArn=template_arn, event=event_type, topicArn=topic_arn ) cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) except Exception as e: cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)}) # 给Lambda配置必要的权限 InspectorSNSSubscriberLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: InspectorSNSSubscriberPermissions PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - inspector:SubscribeToEvent - inspector:UnsubscribeFromEvent Resource: !Ref YourAssessmentTemplate # 替换成你模板里的评估模板资源名 - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: arn:aws:logs:*:*:*
- 添加自定义资源触发Lambda
最后在模板里加一个自定义资源,让CloudFormation在栈创建/更新/销毁时调用上面的Lambda:
InspectorSNSSubscription: Type: Custom::InspectorSNSSubscription Properties: ServiceToken: !GetAtt InspectorSNSSubscriberLambda.Arn AssessmentTemplateArn: !Ref YourAssessmentTemplate # 替换成你的评估模板资源名 SNSTopicArn: !Ref InspectorAlertSNSTopic EventType: ASSESSMENT_RUN_COMPLETED # 可选事件类型:ASSESSMENT_RUN_STARTED、ASSESSMENT_RUN_COMPLETED等
这样一来,部署栈时SNS关联会自动完成,销毁时也会自动清理,完全不用碰控制台。
方案2:用CLI命令在初始化脚本中执行(适合特定场景)
如果你的CFN栈包含EC2实例或者用了CloudFormation Init,也可以在初始化脚本里加一段CLI命令来完成关联:
aws inspector subscribe-to-event \ --resource-arn <你的评估模板ARN> \ --event ASSESSMENT_RUN_COMPLETED \ --topic-arn <你的SNS Topic ARN>
不过这个方案的缺点是需要确保执行命令的环境有正确的IAM权限,而且栈销毁时不会自动取消订阅,得额外写清理逻辑,所以不如方案1省心。
补充:为啥控制台能直接加?
其实控制台背后也是调用了SubscribeToEvent这个API,只是AWS没把这个操作直接封装到AWS::Inspector::AssessmentTemplate资源里,所以我们得用自定义资源来补这个缺口。
内容的提问来源于stack exchange,提问作者Duncan F
相关产品推荐
相关产品推荐

