[AWS]CloudFormation以外からの変更を通知する

CloudFormationで管理している環境で、手で更新してしまって困る!! そんな手で更新した時にすぐ気づくための仕組みです。
2019.02.12

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

コンニチハ、千葉です。

CloudFormation(CFn)のドリフト機能を利用すると、手動で行った変更との差分を確認できます。

AWS CloudFormationで手動で行った変更が検出可能になりました!!!

今回は、CloudFormation外から変更があったタイミングで通知するような設定を行います。通知の部分をどうやって行うかですが、Configのマネージドルールcloudformation-stack-drift-detection-check があり、こちらを利用することで実現します。

やってみた

事前準備

まず、変更検知するためにCFnスタックを作成します。今回は、セキュリティグループを1つだけ作るCFnを用意し、スタックを作成しました。

AWSTemplateFormatVersion: '2010-09-09'
Description: This CloudFormation template to create security group.

Resources:
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: vpc-xxxxxxxx
GroupName: web-sg
GroupDescription: web-sg
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: test
Tags:
- Key: Name
Value: web-sg

こちらのymlを使って、スタックを作成します。

セキュリティグループが作成されていました。

次に、Config Rulesで利用するIAMロールを作成します。 信頼関係には、config.amazonaws.com、 cloudformation.amazonaws.com を指定します。

アクセス権限には、AWSConfigRole、 AWSCloudFormationReadOnlyAccess をアタッチします。

Configの設定

Configが有効化されていない場合は、まず有効化を行いましょう。私の環境はすでに有効化されているため、今回はこの操作はスキップします、適宜有効化してください。 有効化した後、ルールを追加します。

マネージドルール cloudformation-stack-drift-detection-check を選択します。

事前に作成しておいた、CloudFormationのdfirtを実行できる権限を持つIAMロールを指定します。

次に通知の設定をします。ルール評価に関する通知だけ受け取りたいので、CloudWatch Eventsにて通知設定します。 サービス名をconfig、イベントタイプをConfig Rules Compliance Changeで設定します。

評価の結果が変わったタイミングで通知される設定のため、評価NG > OK、評価NG > OKと、両方の場合で通知されます。NGだけ通知するといういいやり方が見つけられなかったので、いったんこれで設定します。

テスト

セキュリティグループを変更してみましょう。通知のタイミングは、Config Rulesで指定した頻度(1時間、2時間、24時間など)のタイミグで評価が実行され、NGの場合は通知されます。

ちゃんと通知されました!改行なしJSONで読みにくいですが"complianceType":"NON_COMPLIANT"と表示があります。(運用するときは整形してみるようにした方がよさそうです。)

{"version":"0","id":"b92daa72-6602-c9fb-1a8b-11a0e6753374","detail-type":"Config Rules Compliance Change","source":"aws.config","account":"XXXXXXXXXXXX","time":"2019-02-09T16:56:05Z","region":"ap-northeast-1","resources":[],"detail":{"resourceId":"arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/drift-test/3a5a72c0-2c76-11e9-b6ac-0675abfcdc76","awsRegion":"ap-northeast-1","awsAccountId":"XXXXXXXXXXXX","configRuleName":"cloudformation-stack-drift-detection-check","recordVersion":"1.0","configRuleARN":"arn:aws:config:ap-northeast-1:XXXXXXXXXXXX:config-rule/config-rule-cki1dm","messageType":"ComplianceChangeNotification","newEvaluationResult":{"evaluationResultIdentifier":{"evaluationResultQualifier":{"configRuleName":"cloudformation-stack-drift-detection-check","resourceType":"AWS::CloudFormation::Stack","resourceId":"arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/drift-test/3a5a72c0-2c76-11e9-b6ac-0675abfcdc76"},"orderingTimestamp":"2019-02-09T16:55:48.002Z"},"complianceType":"NON_COMPLIANT","resultRecordedTime":"2019-02-09T16:56:05.034Z","configRuleInvokedTime":"2019-02-09T16:56:04.007Z"},"oldEvaluationResult":{"evaluationResultIdentifier":{"evaluationResultQualifier":{"configRuleName":"cloudformation-stack-drift-detection-check","resourceType":"AWS::CloudFormation::Stack","resourceId":"arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/drift-test/3a5a72c0-2c76-11e9-b6ac-0675abfcdc76"},"orderingTimestamp":"2019-02-09T15:46:55.369Z"},"complianceType":"COMPLIANT","resultRecordedTime":"2019-02-09T15:47:12.040Z","configRuleInvokedTime":"2019-02-09T15:47:11.238Z"},"notificationCreationTime":"2019-02-09T16:56:05.911Z","resourceType":"AWS::CloudFormation::Stack"}}

最後に

CloudFormation以外から手動で変更された場合に通知する仕組みを作ってみました。Lambdaなどで自前で実装も可能ですが、マネージドなConfig Rulesが用意されているのでこちらを利用するとコードのメンテもないので楽でしょう。いろんな人が触る環境だと、手動変更も起こりやすいので、仕込んでおくと幸せになれそうです。

参考