AWS Configを使ってリソース変更時にSNSでメール通知する

AWS Configを使ってリソース変更時にSNSでメール通知する

以下のページで、AWS Configを使用して、リソースの変更履歴を確認する方法をご紹介しました。

あわせて読みたい
AWS Configでリソースの変更履歴を確認する 【AWS Configでリソースの変更履歴を確認する】 以下のページでAWS Config入門ということで、S3バケットのロギング設定の有効/無効を監査する方法をご紹介しました。 ht...

今回はリソースの変更時に、SNS経由でメールを通知する方法を確認します。

構築する環境

Diagram of email notifications via SNS when resources are changed using AWS Config

構成は冒頭にご紹介したページと概ね同様です。

AWS Configで変更履歴を監視する対象としてS3バケットを作成します。

AWS ConfigにSNSトピックを関連づけ、リソースの変更が発生する度に、メール通知するように設定します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/101

テンプレートファイルのポイント解説

基本的には冒頭でご紹介したページと同様です。

本ページでは、メール通知に関する内容を中心に取り上げます。

SNSトピック

Resources:
  Topic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref MailAddress
          Protocol: email
      TopicName: !Ref Prefix
Code language: YAML (yaml)

SNSトピックを作成し、サブスクライバーとしてメールアドレスを指定します。

詳細につきましては、以下のページをご確認ください。

あわせて読みたい
CFNでSNS入門 – email版 【CFNでSNS入門 - email版】 AWS SNSはメッセージングサービスです。 今回は入門編ということで、通知先にEmailを指定する方法をご紹介します。 【構築する環境】 2種類...

AWS Config

Resources:
  DeliveryChannel:
    Type: AWS::Config::DeliveryChannel
    Properties:
      Name: !Sub "${Prefix}-DeliveryChannel"
      S3BucketName: !Ref ConfigBucket
      SnsTopicARN: !Ref TopicArn
Code language: YAML (yaml)

SnsTopicARNプロパティで、配信チャネルに先ほど定義したSNSトピックのARNを指定します。

AWS Configのアクセス権に関して確認します。

Resources:
  ConfigurationRecorder:
    Type: AWS::Config::ConfigurationRecorder
    Properties:
      Name: !Sub "${Prefix}-ConfigurationRecorder"
      RecordingGroup:
        AllSupported: false
        IncludeGlobalResourceTypes: false
        ResourceTypes:
          - AWS::S3::Bucket
      RoleARN: !GetAtt ConfigRole.Arn

  ConfigRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Delete
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - config.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWS_ConfigRole
      Policies:
        - PolicyName: SNSPublishPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - sns:Publish
                Resource:
                  - !Ref TopicArn
Code language: YAML (yaml)

SNS経由で変更を通知するためには、SNSトピックにメッセージをパブリッシュする権限(sns:Publish)が必要です。
冒頭でご紹介したページでは、サービスにリンクされたロール(SLR)を使用していましたが、本ロールでは、このアクションを許可していません。
ですからAWS管理ポリシーAWS_ConfigRoleをベースとして、インラインポリシーとしてsns:Publishを追加したロールを用意します。
このロールをAWS Configの設定レコーダに指定します。

(参考)S3バケット

Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${Prefix}-encryption-enabled"
      AccessControl: Private
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
Code language: YAML (yaml)

検証用リソースとしてS3バケットを用意します。
SSEを有効化します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • SNSトピック:fa-101
  • 検証用バケット:fa-101-encryption-enabled

メールアドレスの認証

SNSトピックのサブスクライバーとしてメールアドレスを指定した場合、そのメールアドレスを認証する必要があります。
指定したメールアドレスに、以下のような認証メールが送られてきます。

Detail of SNS 1

「Confirm subscription」を押下して、認証を進めます。

Detail of SNS 2

上記のページが表示されて、認証が完了したことがわかります。

リソース確認

AWS Management Consoleから各リソースを確認します。
まずSNSトピックを確認します。

Detail of SNS 3
Detail of SNS 4

正常にSNSトピックが作成されていることがわかります。

加えて、サブスクライバーとして登録したメールアドレスが登録されていることもわかります。
またこのメールアドレスのStatusの値を見ると「Confirmed」とあり、認証が完了していることもわかります。

AWS Configの設定を確認します。

Detail of AWS Config 1

Delivery methodのSNS topic nameを見ると、先述のSNSトピック名が確認できます。
確かにAWS ConfigにSNSが関連づいています。

検証用S3バケットを確認します。

Detail of S3 1

S3バケットが正常に作成されています。
特にDefault encryptionの項目を見ると、暗号化が有効化されていることがわかります。

動作確認

準備が整いましたので、実際の動作を確認します。

リソース作成

先述のS3バケットが作成された際に、SNSトピックに指定したメールアドレスに以下のメールが届きました。
以下の画像がその一部です。

Detail of SNS 5

以下がデータのサンプルです。

{
	"configurationItemDiff": {
		"changedProperties": {},
		"changeType": "CREATE"
	},
	"configurationItem": {
		"relatedEvents": [],
		"relationships": [],
		"configuration": {
			"name": "fa-101-encryption-enabled",
			"owner": {
				"displayName": null,
				"id": "cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa"
			},
			"creationDate": "2022-11-24T12:36:41.000Z"
		},
		"supplementaryConfiguration": {
			"AccessControlList": "{\"grantSet\":null,\"grantList\":[{\"grantee\":{\"id\":\"cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa\",\"displayName\":null},\"permission\":\"FullControl\"}],\"owner\":{\"displayName\":null,\"id\":\"cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa\"},\"isRequesterCharged\":false}",
			"BucketAccelerateConfiguration": {
				"status": null
			},
			"BucketLoggingConfiguration": {
				"destinationBucketName": null,
				"logFilePrefix": null
			},
			"BucketNotificationConfiguration": {
				"configurations": {}
			},
			"BucketPolicy": {
				"policyText": null
			},
			"BucketTaggingConfiguration": {
				"tagSets": [
					{
						"tags": {
							"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/fa-101-S3Stack2-15643EG8FNO7M/a1deaa30-6bf4-11ed-bbbe-0efc92e64d09",
							"aws:cloudformation:stack-name": "fa-101-S3Stack2-15643EG8FNO7M",
							"aws:cloudformation:logical-id": "Bucket"
						}
					}
				]
			},
			"BucketVersioningConfiguration": {
				"status": "Off",
				"isMfaDeleteEnabled": null
			},
			"IsRequesterPaysEnabled": false,
			"ServerSideEncryptionConfiguration": {
				"rules": [
					{
						"applyServerSideEncryptionByDefault": {
							"sseAlgorithm": "AES256",
							"kmsMasterKeyID": null
						},
						"bucketKeyEnabled": false
					}
				]
			}
		},
		"tags": {
			"aws:cloudformation:stack-name": "fa-101-S3Stack2-15643EG8FNO7M",
			"aws:cloudformation:logical-id": "Bucket",
			"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/fa-101-S3Stack2-15643EG8FNO7M/a1deaa30-6bf4-11ed-bbbe-0efc92e64d09"
		},
		"configurationItemVersion": "1.3",
		"configurationItemCaptureTime": "2022-11-24T12:38:50.768Z",
		"configurationStateId": 1669293530768,
		"awsAccountId": "[account-id]",
		"configurationItemStatus": "ResourceDiscovered",
		"resourceType": "AWS::S3::Bucket",
		"resourceId": "fa-101-encryption-enabled",
		"resourceName": "fa-101-encryption-enabled",
		"ARN": "arn:aws:s3:::fa-101-encryption-enabled",
		"awsRegion": "ap-northeast-1",
		"availabilityZone": "Regional",
		"configurationStateMd5Hash": "",
		"resourceCreationTime": "2022-11-24T12:36:41.000Z"
	},
	"notificationCreationTime": "2022-11-24T12:38:50.832Z",
	"messageType": "ConfigurationItemChangeNotification",
	"recordVersion": "1.3"
}
Code language: JSON / JSON with Comments (json)

S3バケットの作成状況が読み取れます。

AWS Configによるリソースの変更履歴も確認します。

Detail of AWS Config 2

バケットの作成(CreateBucket))と、暗号化の設定(PutBucketEncryption)が実行されたことがわかります。

リソース設定変更

次にS3バケットの設定を変更し、その際の挙動を確認します。
具体的には、バケットの暗号化を無効化します。

Detail of S3 2

しばらく待機すると、以下のメールが届きました。

Detail of SNS 6

以下が全内容です。

{
	"configurationItemDiff": {
		"changedProperties": {
			"SupplementaryConfiguration.ServerSideEncryptionConfiguration": {
				"previousValue": {
					"rules": [
						{
							"applyServerSideEncryptionByDefault": {
								"sseAlgorithm": "AES256",
								"kmsMasterKeyID": null
							},
							"bucketKeyEnabled": false
						}
					]
				},
				"updatedValue": null,
				"changeType": "DELETE"
			}
		},
		"changeType": "UPDATE"
	},
	"configurationItem": {
		"relatedEvents": [],
		"relationships": [],
		"configuration": {
			"name": "fa-101-encryption-enabled",
			"owner": {
				"displayName": null,
				"id": "cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa"
			},
			"creationDate": "2022-11-24T12:36:41.000Z"
		},
		"supplementaryConfiguration": {
			"AccessControlList": "{\"grantSet\":null,\"grantList\":[{\"grantee\":{\"id\":\"cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa\",\"displayName\":null},\"permission\":\"FullControl\"}],\"owner\":{\"displayName\":null,\"id\":\"cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa\"},\"isRequesterCharged\":false}",
			"BucketAccelerateConfiguration": {
				"status": null
			},
			"BucketLoggingConfiguration": {
				"destinationBucketName": null,
				"logFilePrefix": null
			},
			"BucketNotificationConfiguration": {
				"configurations": {}
			},
			"BucketPolicy": {
				"policyText": null
			},
			"BucketTaggingConfiguration": {
				"tagSets": [
					{
						"tags": {
							"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/fa-101-S3Stack2-15643EG8FNO7M/a1deaa30-6bf4-11ed-bbbe-0efc92e64d09",
							"aws:cloudformation:stack-name": "fa-101-S3Stack2-15643EG8FNO7M",
							"aws:cloudformation:logical-id": "Bucket"
						}
					}
				]
			},
			"BucketVersioningConfiguration": {
				"status": "Off",
				"isMfaDeleteEnabled": null
			},
			"IsRequesterPaysEnabled": false
		},
		"tags": {
			"aws:cloudformation:stack-name": "fa-101-S3Stack2-15643EG8FNO7M",
			"aws:cloudformation:logical-id": "Bucket",
			"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/fa-101-S3Stack2-15643EG8FNO7M/a1deaa30-6bf4-11ed-bbbe-0efc92e64d09"
		},
		"configurationItemVersion": "1.3",
		"configurationItemCaptureTime": "2022-11-24T12:47:31.787Z",
		"configurationStateId": 1669294051787,
		"awsAccountId": "[account-id]",
		"configurationItemStatus": "OK",
		"resourceType": "AWS::S3::Bucket",
		"resourceId": "fa-101-encryption-enabled",
		"resourceName": "fa-101-encryption-enabled",
		"ARN": "arn:aws:s3:::fa-101-encryption-enabled",
		"awsRegion": "ap-northeast-1",
		"availabilityZone": "Regional",
		"configurationStateMd5Hash": "",
		"resourceCreationTime": "2022-11-24T12:36:41.000Z"
	},
	"notificationCreationTime": "2022-11-24T12:47:31.828Z",
	"messageType": "ConfigurationItemChangeNotification",
	"recordVersion": "1.3"
}
Code language: JSON / JSON with Comments (json)

アップデートによって、暗号化に関する設定が削除されたことがわかります。

AWS Configによるリソースの変更履歴も確認します。

Detail of AWS Config 3

暗号化設定の削除(DeleteBucketEncryption)が実行されたことがわかります。

リソース削除

しばらく待機すると、以下のメールが届きました。

Detail of S3 3

以下が全内容です。

{
	"configurationItemDiff": {
		"changedProperties": {
			"SupplementaryConfiguration.BucketAccelerateConfiguration": {
				"previousValue": {
					"status": null
				},
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"Tags.1": {
				"previousValue": "Bucket",
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"Tags.2": {
				"previousValue": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/fa-101-S3Stack2-15643EG8FNO7M/a1deaa30-6bf4-11ed-bbbe-0efc92e64d09",
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"Configuration": {
				"previousValue": {
					"name": "fa-101-encryption-enabled",
					"owner": {
						"displayName": null,
						"id": "cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa"
					},
					"creationDate": "2022-11-24T12:36:41.000Z"
				},
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"SupplementaryConfiguration.IsRequesterPaysEnabled": {
				"previousValue": false,
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"Tags.0": {
				"previousValue": "fa-101-S3Stack2-15643EG8FNO7M",
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"SupplementaryConfiguration.BucketLoggingConfiguration": {
				"previousValue": {
					"destinationBucketName": null,
					"logFilePrefix": null
				},
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"SupplementaryConfiguration.BucketTaggingConfiguration": {
				"previousValue": {
					"tagSets": [
						{
							"tags": {
								"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:[account-id]:stack/fa-101-S3Stack2-15643EG8FNO7M/a1deaa30-6bf4-11ed-bbbe-0efc92e64d09",
								"aws:cloudformation:stack-name": "fa-101-S3Stack2-15643EG8FNO7M",
								"aws:cloudformation:logical-id": "Bucket"
							}
						}
					]
				},
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"SupplementaryConfiguration.BucketPolicy": {
				"previousValue": {
					"policyText": null
				},
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"SupplementaryConfiguration.BucketNotificationConfiguration": {
				"previousValue": {
					"configurations": {}
				},
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"SupplementaryConfiguration.AccessControlList": {
				"previousValue": "{\"grantSet\":null,\"grantList\":[{\"grantee\":{\"id\":\"cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa\",\"displayName\":null},\"permission\":\"FullControl\"}],\"owner\":{\"displayName\":null,\"id\":\"cd3b764ff044236dfe910b663c273b1f98dd3299f4d524a32909f70581c332fa\"},\"isRequesterCharged\":false}",
				"updatedValue": null,
				"changeType": "DELETE"
			},
			"SupplementaryConfiguration.BucketVersioningConfiguration": {
				"previousValue": {
					"status": "Off",
					"isMfaDeleteEnabled": null
				},
				"updatedValue": null,
				"changeType": "DELETE"
			}
		},
		"changeType": "DELETE"
	},
	"configurationItem": {
		"relatedEvents": [],
		"relationships": [],
		"configuration": null,
		"supplementaryConfiguration": {},
		"tags": {},
		"configurationItemVersion": "1.3",
		"configurationItemCaptureTime": "2022-11-24T12:58:58.374Z",
		"configurationStateId": 1669294738374,
		"awsAccountId": "[account-id]",
		"configurationItemStatus": "ResourceDeleted",
		"resourceType": "AWS::S3::Bucket",
		"resourceId": "fa-101-encryption-enabled",
		"resourceName": "fa-101-encryption-enabled",
		"ARN": "arn:aws:s3:::fa-101-encryption-enabled",
		"awsRegion": "ap-northeast-1",
		"availabilityZone": null,
		"configurationStateMd5Hash": "",
		"resourceCreationTime": null
	},
	"notificationCreationTime": "2022-11-24T12:58:58.422Z",
	"messageType": "ConfigurationItemChangeNotification",
	"recordVersion": "1.3"
}
Code language: JSON / JSON with Comments (json)

バケットが削除されたことがわかります。

AWS Configによるリソースの変更履歴も確認します。

Detail of AWS Config 4

バケット削除(DeleteBucket)が実行されたことがわかります。

このようにAWS ConfigにSNSを関連づけることによって、リソースの変更時にメール通知することができます。

まとめ

リソースの変更時に、SNS経由でメールを通知する方法を確認しました。