記事公開日
最終更新日
AWS CloudFormation活用 - AWS ConfigをCloudFormationで設定する際のハマりポイント

こんにちは。システムソリューション営業本部の松浦です。
今回はCloudFormationを使用して、AWS Configを有効化する方法と、
有効化時のハマりポイントをご紹介いたします。
AWS Configは有効化するだけでリソースの変更追跡などが行える便利なサービスです。
AWSドキュメント - AWS Config とは?
以下ドキュメントに記載のリソースタイプがサポートされています。
(VPCやEC2等の主要サービスを含めた幅広い範囲でサポートされていますね)
AWSドキュメント - サポートされているリソースタイプ
CloudFormationを使用することでAWS Configのログ用S3バケットやIAMロール等、
関連リソースの設定もまとめて行うことが可能です。
まずは成功例のご紹介
ハマりポイントご紹介の前に、まずは成功する方法(最終版テンプレート)をご紹介します。後述のハマりポイントを考慮して修正した最終形となっていますので、「とりあえず設定したい!」という方はこちらのテンプレートをご活用下さい。
以下をクリックすることで表示されるコード部分をそれぞれテキストエディタにコピペし、拡張子をyamlとして任意のファイル名で保存します。
■AWS Config用テンプレート(クリックしてテンプレートを表示)
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
BucketName:
Type: String
Resources:
# Configログ出力バケットの定義
ConfigLogS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
# Configログ出力バケット用バケットポリシーの定義
ConfigLogS3BucketPolicy:
Type: AWS::S3::BucketPolicy
DependsOn: ConfigLogS3Bucket
Properties:
Bucket: !Ref ConfigLogS3Bucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:GetBucketAcl
Resource: !Sub arn:aws:s3:::${ConfigLogS3Bucket}
- Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:PutObject
Resource: !Sub arn:aws:s3:::${ConfigLogS3Bucket}/AWSLogs/${AWS::AccountId}/Config/*
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
- Sid: AllowSSLRequestsOnly
Effect: Deny
Principal: '*'
Action: s3:*
Resource:
- !Sub arn:aws:s3:::${ConfigLogS3Bucket}
- !Sub arn:aws:s3:::${ConfigLogS3Bucket}/*
Condition:
Bool:
aws:SecureTransport: false
# Config用サービスリンクロールの定義
ConfigRole:
Type: AWS::IAM::ServiceLinkedRole
Properties:
AWSServiceName: config.amazonaws.com
# ConfigurationRecorderの定義 (Configレコーダーの有効化)
ConfigRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn: ConfigLogS3Bucket
Properties:
RecordingGroup:
AllSupported: true
IncludeGlobalResourceTypes: true
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
# ConfigDeliveryChannelの定義 (ログ配信の有効化) ※今回は実施しないが、SNS通知もここで有効化可能
ConfigDeliveryChannel:
Type: AWS::Config::DeliveryChannel
DependsOn: ConfigLogS3Bucket
Properties:
S3BucketName: !Ref ConfigLogS3Bucket
・Configログ保管用S3バケット
・Configログ保管用S3バケット用のバケットポリシー
・Config用IAMロール
・Configレコーダー有効化
・ConfigDeliveryChannel(ログ配信)の有効化
実行してみる
それではこのテンプレートを使用してCloudFormationでスタックを作成してみましょう!
・CloudFormationスタックを作成します。
Cloudformation - スタック - スタックの作成 - 新しいリソースを使用(標準)
("スタックの作成"画面)
・使用するテンプレートを選択します。
※S3使用 or ファイルアップロードはご使用の環境に応じて任意の方法を選択して下さい
テンプレートの準備完了
- 「Amazon S3 URL」 または 「テンプレートファイルのアップロード」を指定
- テンプレートのS3URLを入力 または テンプレートファイルをアップロード
- 次へ
("スタックの詳細を指定"画面)
・スタック名と各種パラメータを入力します。
スタック名を入力 - 各種パラメータを入力 - 次へ
<スタックの名前>
・任意の値を入力(今回は「config-setup」とします)
<パラメーター>
・BucketName:Configログ保管用S3バケットの任意の名前を入力します
("スタックオプションの設定"画面)
・今回はスタックオプションは使用せず、デフォルトのままとします。
何も変更せずに画面下部へスクロールし「次へ」を押下
↓スクロール
("レビュー"画面)
・設定内容の確認画面です。内容に問題が無い事を確認後、スタックを作成します。
画面下部へスクロールし「送信」を押下
↓スクロール
(スタックのイベント画面)
スタックのイベント画面に遷移します。
スタックおよび各種リソースの作成状況のイベントを参照することができます。
論理ID「config-setup」(スタック名)のステータスが「CREATE_COMPLETE」となればスタックおよび各種リソースの作成が完了です!
これだけでAWS Configの有効化が完了です!
試しにConfigのサービス画面を見てみましょう。
サービス - AWS Config - 設定
「レコーダー」設定として、以下がCloudFormationにより設定されていますね。
・「記録はオン」となっている
・「AWS Configロール」が「AWSServiceRoleForConfig」となっている
少し下にスクロールすると、「配信方法」の設定が参照できます。
「配信方法」では作成したS3バケット(qes~)の指定が問題無く行えていることが確認できますね。
これでConfigが有効化され、S3やIAMとの連携も行われていることを確認できました!
以上がConfig有効化のご紹介となります。ご活用いただけますと幸いです!
(本題)ハマりポイントのご紹介
前置きが長くなってしまいましたが、ここからはAWS ConfigをCloudFormationで構築する際のハマりポイントをご紹介します。
CloudFormationテンプレートでは、DependsOn属性を使用してリソースの作成順序を制御可能です。
(例えば今回も「バケットポリシーはバケットの作成が終わってから作ってね」といった制御をしています)
今回ご紹介したテンプレートでは、Config用のリソースとして以下の2点を定義しています。
・AWS::Config::ConfigurationRecorder
→Confignのサービス画面の「レコーダー」にあたるリソースです。
・AWS::Config::DeliveryChannel
→Confignのサービス画面の「配信方法」にあたるリソースです。
ここで、CloudFormationのAWS::Config::ConfigurationRecorderのドキュメントを見てみると以下の記載があります。
Note
To enable AWS Config, you must create a configuration recorder and a delivery channel.
If you want to create the resources separately, you must create a configuration recorder before you can create a delivery channel.
AWS Config uses the configuration recorder to capture configuration changes to your resources. For more information, see AWS::Config::ConfigurationRecorder.
「リソースを個別で作る時はDeliveryChannelを作る前にConfigurationRecorderを作ってね」という記載に見えますね。
じゃあ一応DependOnで順番制御しておくか・・・ということで、順番制御を反映したテンプレートを実行してみましょう。
ConfigurationRecorderの後にDeliveryChannelを設定するよう、以下テンプレートを使用します。
■上手く動かないテンプレート例-その1(クリックしてテンプレートを表示)
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
BucketName:
Type: String
Resources:
# Configログ出力バケットの定義
ConfigLogS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
# Configログ出力バケット用バケットポリシーの定義
ConfigLogS3BucketPolicy:
Type: AWS::S3::BucketPolicy
DependsOn: ConfigLogS3Bucket
Properties:
Bucket: !Ref ConfigLogS3Bucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:GetBucketAcl
Resource: !Sub arn:aws:s3:::${ConfigLogS3Bucket}
- Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:PutObject
Resource: !Sub arn:aws:s3:::${ConfigLogS3Bucket}/AWSLogs/${AWS::AccountId}/Config/*
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
- Sid: AllowSSLRequestsOnly
Effect: Deny
Principal: '*'
Action: s3:*
Resource:
- !Sub arn:aws:s3:::${ConfigLogS3Bucket}
- !Sub arn:aws:s3:::${ConfigLogS3Bucket}/*
Condition:
Bool:
aws:SecureTransport: false
# Config用サービスリンクロールの定義
ConfigRole:
Type: AWS::IAM::ServiceLinkedRole
Properties:
AWSServiceName: config.amazonaws.com
# ConfigurationRecorderの定義 (Configレコーダーの有効化)
ConfigRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn:
- ConfigLogS3Bucket
Properties:
RecordingGroup:
AllSupported: true
IncludeGlobalResourceTypes: true
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
# ConfigDeliveryChannelの定義 (ログ配信の有効化) ※今回は実施しないが、SNS通知もここで有効化可能
ConfigDeliveryChannel:
Type: AWS::Config::DeliveryChannel
DependsOn:
- ConfigLogS3Bucket
- ConfigRecorder #★ここで順番制御
Properties:
S3BucketName: !Ref ConfigLogS3Bucket
このテンプレートを使ってスタックを作成します。※スタック作成の経過画面は割愛いたします
すると・・・
エラーが出力し、スタック作成に失敗しました。
以下エラーメッセージが出力していますね。
「Delivery channel is not available to start configuration recorder.」
エラーメッセージ的にDeliveryChannelを先に作るのかなぁ・・・
ドキュメントと矛盾してる気がするしピンとこないなぁ・・・
と思いながらテンプレートを修正します。
作成順を入れ替え、DeliveryChannelの後にConfigurationRecorderを設定するように修正した以下テンプレートを使用します。
■上手く動かないテンプレート例-その2(クリックしてテンプレートを表示)
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
BucketName:
Type: String
Resources:
# Configログ出力バケットの定義
ConfigLogS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
# Configログ出力バケット用バケットポリシーの定義
ConfigLogS3BucketPolicy:
Type: AWS::S3::BucketPolicy
DependsOn: ConfigLogS3Bucket
Properties:
Bucket: !Ref ConfigLogS3Bucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:GetBucketAcl
Resource: !Sub arn:aws:s3:::${ConfigLogS3Bucket}
- Effect: Allow
Principal:
Service: config.amazonaws.com
Action: s3:PutObject
Resource: !Sub arn:aws:s3:::${ConfigLogS3Bucket}/AWSLogs/${AWS::AccountId}/Config/*
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
- Sid: AllowSSLRequestsOnly
Effect: Deny
Principal: '*'
Action: s3:*
Resource:
- !Sub arn:aws:s3:::${ConfigLogS3Bucket}
- !Sub arn:aws:s3:::${ConfigLogS3Bucket}/*
Condition:
Bool:
aws:SecureTransport: false
# Config用サービスリンクロールの定義
ConfigRole:
Type: AWS::IAM::ServiceLinkedRole
Properties:
AWSServiceName: config.amazonaws.com
# ConfigDeliveryChannelの定義 (ログ配信の有効化) ※今回は実施しないが、SNS通知もここで有効化可能
ConfigDeliveryChannel:
Type: AWS::Config::DeliveryChannel
DependsOn:
- ConfigLogS3Bucket
Properties:
S3BucketName: !Ref ConfigLogS3Bucket
# ConfigurationRecorderの定義 (Configレコーダーの有効化)
ConfigRecorder:
Type: AWS::Config::ConfigurationRecorder
DependsOn:
- ConfigLogS3Bucket
- ConfigDeliveryChannel #★ここで順番制御
Properties:
RecordingGroup:
AllSupported: true
IncludeGlobalResourceTypes: true
RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
このテンプレートを使ってスタックを作成します。※経過画面は割愛
やっぱりダメでしたね。
エラーメッセージは以下の通りです。
「Configuration recorder is not available to put delivery channel.」
と、上記の様にどちらかをDependsOnするとConfigの有効化に失敗することがわかります。
調べてみたところ、「AWS::Config::ConfigurationRecorder」と「AWS::Config::DeliveryChannel」は
お互いに循環依存の関係にあるため、どちらかをDependsOnするとリソース作成の処理が途中で止まり、
CloudFormationがタイムアウトする様です。
※AWSのIssueも存在しています:リンク
→つまり、「AWS::Config::ConfigurationRecorder」と「AWS::Config::DeliveryChannel」は
お互いにDepensOnしてはいけない。という仕様があるということですね。
CloudFormationに慣れていると逆にハマりがちなポイントかと思うのでご注意ください!
まとめ
最後までお読みいただき、誠にありがとうございました!
CloudFormationでのAWS Configの設定方法と、設定時のハマりポイントをご紹介いたしました。
AWS Configはとりあえず有効化しておいていいレベルの便利なサービスかと思いますので、
本記事をご活用頂き設定の一助にして頂ければ幸いです。
もし「このサービスについて知りたい」「AWS環境の構築、移行」などのリクエストがございましたら、弊社お問合せフォームまでお気軽にご連絡ください! のちほど当ブログにてご紹介させていただくか、複雑な内容に関するお問い合わせの内容の場合には直接営業からご連絡を差し上げます。
また、よろしければ以下のリンクもご覧ください!
<QES関連ソリューション/ブログ>
<QESが参画しているAWSのセキュリティ推進コンソーシアムがホワイトペーパーを公開しました>
※Amazon Web Services、”Powered by Amazon Web Services”ロゴ、およびブログで使用されるその他のAWS商標は、米国その他の諸国における、Amazon.com, Inc.またはその関連会社の商標です。