『タグなしポイ捨てリソース、ダメ絶対!!』Config非準拠判定でSNSメール通知構築ハンズオン


この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。

はじめに

年末の大掃除ということで、会社内の検証環境を改めて確認しました。メンバーが多くなると仕方ない部分かとは思いますが、タグが付与されていない野良リソースとも言える、どこで誰がなんの目的でつくったかも分からない放置リソースが多く目立ちます。

タグなしポイ捨てリソース、ダメ絶対というこで、リソースの片付け第一弾として、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リソースが少ないのも現実なので、もっと改善していかなければいけないなと。
とはいえ、まずは小さいことから少しずつ始めて、年末のリソース大掃除をしていきたいと思います。

Last modified: 2022-12-30

Author