はじめに
年末の大掃除ということで、会社内の検証環境を改めて確認しました。メンバーが多くなると仕方ない部分かとは思いますが、タグが付与されていない野良リソースとも言える、どこで誰がなんの目的でつくったかも分からない放置リソースが多く目立ちます。
タグなしポイ捨てリソース、ダメ絶対
というこで、リソースの片付け第一弾として、Configルールを利用して非準拠判定が出たらSNSでメンバーに通知が行くような構築をしていきたいと思います。
構成図
ハンズオン
構築の流れ
1.SNS作成
2.AWS Config作成
3.EventBridge作成
上記の順番で構築を行なっていきます。
最終的には、CFnのスタックにタグが付与されていないことをConfigのルールで検知して、その検知したことをEventBridge経由でSNSを利用してメールを送信します。
1.SNS作成
1.1 SNSを構築する
Configで非準拠判定された場合に通知する、SNSトピックを構築します。
TopicPolicy
部分は、検証のため制限していません。
構築後サブスクリプション
AWSTemplateFormatVersion: "2010-09-09"
Description: SNS Create
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "SNS Configuration"
Parameters:
- TopicName
- Endpoint
ParameterLabels:
TopicName:
default: "TopicName"
Endpoint:
default: "MailAddress"
# ------------------------------------------------------------#
# InputParameters
# ------------------------------------------------------------#
Parameters:
TopicName:
Type: String
Default: "cfn-sns-topic-inamura"
Endpoint:
Type: String
Default: "XXXXXXXXXX@gmail.com"
TagsValueUserName:
Type: String
Default: "inamura"
# ------------------------------------------------------------#
# Resources
# ------------------------------------------------------------#
Resources:
SNSTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: !Ref TopicName
Subscription:
- Endpoint: !Ref Endpoint
Protocol: email
Tags:
- Key: "User"
Value: !Ref TagsValueUserName
TopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
Topics:
- !Ref SNSTopic
PolicyDocument:
Id: !Ref SNSTopic
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: "*"
Action: SNS:Publish
Resource: !Ref SNSTopic
# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#
Outputs:
SNSArn:
Value: !Ref SNSTopic
Export:
Name: !Sub "${TopicName}-arn"
SNSTopicName:
Value: !Ref TopicName
Export:
Name: !Ref TopicName
1.2 上記設定後に、SNSから送られてきたメールのサブスクリプションを押下する
②画面が遷移して下記画面が表示されると、サブスクリプションが開始される
※上記青枠部分をクリックすると、サブスクリプションが解除される
2.AWS Config作成
運用している状況によりますが、今回はtag1Key
で付与しなければいけないタグのみを設定します(このtag1Key
が付与されていないと非準拠判定される)
適応可能なAWSリソースの詳細は、AWS Configデベロッパーガイド > required-tags
に記載されていますが、今回はその中のCFnのスタックにタグが付与されていない場合のみ反応するよう、不要リソース部分はコメントアウトしています。
AWSTemplateFormatVersion: '2010-09-09'
Description:
Config Rule required-tags check
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "AWS Config Configuration"
Parameters:
- ConfigRuleName
- tag1Key
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
ConfigRuleName:
Description: "config rule(required-tags) name"
Type: String
Default: cfn-con-requiredtags-inamura
tag1Key:
Description: "Key of the required tag."
Type: String
Default: User
# ------------------------------------------------------------#
# Resource
# ------------------------------------------------------------#
Resources:
ConfigRule:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: !Ref ConfigRuleName
Description: "リソースに、指定するタグがリソースにあるかどうかを確認します。例えば、'Name'タグが EC2 インスタンスに存在するかどうかを確認できます。複数の値はカンマで区切ります。"
Source:
Owner: AWS
SourceIdentifier: REQUIRED_TAGS
InputParameters:
tag1Key: !Ref tag1Key
Scope:
ComplianceResourceTypes:
# - "AWS::ACM::Certificate"
# - "AWS::AutoScaling::AutoScalingGroup"
- "AWS::CloudFormation::Stack"
# - "AWS::CodeBuild::Project"
# - "AWS::DynamoDB::Table"
# - "AWS::EC2::CustomerGateway"
# - "AWS::EC2::Instance"
# - "AWS::EC2::InternetGateway"
# - "AWS::EC2::NetworkAcl"
# - "AWS::EC2::NetworkInterface"
# - "AWS::EC2::RouteTable"
# - "AWS::EC2::SecurityGroup"
# - "AWS::EC2::Subnet"
# - "AWS::EC2::Volume"
# - "AWS::EC2::VPC"
# - "AWS::EC2::VPNConnection"
# - "AWS::EC2::VPNGateway"
# - "AWS::ElasticLoadBalancing::LoadBalancer"
# - "AWS::ElasticLoadBalancingV2::LoadBalancer"
# - "AWS::RDS::DBInstance"
# - "AWS::RDS::DBSecurityGroup"
# - "AWS::RDS::DBSnapshot"
# - "AWS::RDS::DBSubnetGroup"
# - "AWS::RDS::EventSubscription"
# - "AWS::Redshift::Cluster"
# - "AWS::Redshift::ClusterParameterGroup"
# - "AWS::Redshift::ClusterSecurityGroup"
# - "AWS::Redshift::ClusterSnapshot"
# - "AWS::Redshift::ClusterSubnetGroup"
# - "AWS::S3::Bucket"
3.EventBridge作成
デフォルトのメッセージが送られてくるのも味気ないのでInputTransformer
部分を記述することで、いつ発生したのか?や、Config画面へアクセスして詳細がわかるようなURLなどが、SNSの内容に盛り込まれるようにしています。
EventBridgeに対してのタグは[ユーザーガイド AWS::Events::Rule Tag]より出来ないようです。(https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-tag.html)
AWSTemplateFormatVersion: "2010-09-09"
Description:
Using Config Tag Rules,use by EventBridge and email by SNS
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "Eventbridge Configuration"
Parameters:
- Name
- EventBusName
- State
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
EventBusName:
Type: String
Default: "default"
Name:
Type: String
Default: "cfn-evb-tagrule-inamura"
State:
Type: String
Default: "ENABLED"
# ------------------------------------------------------------#
# EventBridge
# ------------------------------------------------------------#
Resources:
EventsRule:
Type: AWS::Events::Rule
Properties:
Description: "Using Config Tag Rules,use by EventBridge and email by SNS"
EventBusName: !Ref EventBusName
Name: !Ref Name
State: !Ref State
EventPattern:
source:
- aws.config
detail-type:
- Config Rules Compliance Change
detail:
messageType:
- ComplianceChangeNotification
configRuleName:
- cfn-con-requiredtags-inamura
newEvaluationResult:
complianceType:
- NON_COMPLIANT
Targets:
- Arn: !ImportValue cfn-sns-topic-inamura-arn
Id: "cfn-sns-topic-transfer"
InputTransformer:
InputPathsMap:
"awsRegion": "$.detail.awsRegion"
"resourceType": "$.detail.resourceType"
"resourceId": "$.detail.resourceId"
"time": "$.detail.newEvaluationResult.resultRecordedTime"
"compliance": "$.detail.newEvaluationResult.complianceType"
"rule": "$.detail.configRuleName"
InputTemplate: |
"Userタグのないリソースが作成されました!"
"発生時間 : <time>"
"ルール名 : <rule>"
"リソースタイプ : <resourceType>"
"リソースID : <resourceId>"
"上記リソースが <compliance> 判定となりました。"
"詳細は以下URLよりご確認ください。"
"https://<awsRegion>.console.aws.amazon.com/config/home?region=<awsRegion>#/resources/details?resourceId=<resourceId>&resourceType=<resourceType>"
挙動の確認
①CFnでタグ
をつけず構築する
②SNSでメールが受信できる
デフォルトの通知よりは見やすくて、詳細にアクセスできるのも助かるかと思います。
さいごに
タグなしポイ捨てリソース、ダメ絶対
とはいえConfigでは、対象にできるAWSリソースが少ないのも現実なので、もっと改善していかなければいけないなと。
とはいえ、まずは小さいことから少しずつ始めて、年末のリソース大掃除をしていきたいと思います。