AWS Configの一番簡単なCloudFormationサンプル

# はじめに
ソリューションアーキテクトプロフェッショナルの勉強をしていて、たびたび出てくるAWS Configが気になったので、CloudFormationで作ってみました。

# 参考
https://qiita.com/akashima/items/2cde33863c923c41ed8f

# 知識面
よくある「よくない設定をしたら検知」の環境を構築する例を考えます。

1. まず、事前に以下を作ります。
    - S3
        - 情報の保存先
    - IAMロール
        - AWS Configが行う操作がまとめて許可されたポリシーを付与
        - 上記S3への書き込み権限を付与


2. 次に以下の2つを一緒に作ります。リージョンに一つだけ作れます。
    - レコーダー
        - 設定を収集するリソースのタイプを設定
    - 配信チャンネル
        - レコーダーが収集した情報の保存先を設定

3. 最後に検知の仕組みを作ります。
    - ルール
        - 検知しようとしている「よくない設定」を設定


上記について、コンソールとCLIから作るとどうなるのか、公式の記載について以下にまとめてみました。

## コンソールから作る場合（1-Clickセットアップ）
https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/1-click-setup.html

- S3 : 決められた名前で自動作成。既にある場合はそのまま利用。
- IAMロール : 自動で作成。
- レコーダー : すべてのリソースが対象。
- 配信チャンネル : 決められた名前のバケットに出力。
- ルール : 作成されない。自分で要作成。

全てのリソースを対象として作成されます。リソースを作成・変更するたびにConfigが記録し課金が発生しますので、よくハンズオンなどされる方は気を付けた方が良いかと思います。

## コンソールから作る場合（手動セットアップ）
https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/manual-setup.title.html

- S3 : 自動作成、または自身で作成したものを指定可能。
- IAMロール : 自動作成、または自身で作成したものを指定可能。
- レコーダー : すべて、または任意で選択可能。
- 配信チャンネル : 指定したS3に出力。SNSを追加で指定可能。
- ルール : 指定可能。スキップも可能。

「特定のリソースタイプのみ監視」の場合はこちらがいいです。ルールも一緒に作ることができます。

## CLIから作る場合
https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/gs-cli.html

- S3 : 要事前作成。
- IAMロール : 要事前作成。
- レコーダー : 要作成。
    - 作っただけでは起動せず、配信チャンネル作成後に要起動。
- 配信チャンネル : 要作成。 
- ルール : 要作成。

# CloudFormationで作成
ここからは自作した部分になります。

コードは以下のようになります。シンプルにS3、IAMロール、レコーダー、配信チャンネルの4つを作っています。
監視リソースタイプはS3のみで、作成したS3に出力します。
出力先のS3は、削除時に中身があるとエラーになるので、DeletionPolicy: Retain(保持)にしています。

```yaml
AWSTemplateFormatVersion: 2010-09-09

Resources:
  BucketForDeliveryChannel:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain

  RoleForConfigRecorder:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - config.amazonaws.com
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWS_ConfigRole
      Policies:
        # 配信先への書き込み権限
        - PolicyName: ConfigPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject*
                Resource:
                  - !Sub arn:aws:s3:::${BucketForDeliveryChannel}/*
                Condition:
                  StringLike:
                    s3:x-amz-acl: bucket-owner-full-control

  ConfigRecorder:
    Type: AWS::Config::ConfigurationRecorder
    Properties:
      RoleARN: !GetAtt RoleForConfigRecorder.Arn
      RecordingGroup:
        # https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/resource-config-reference.html
        ResourceTypes:
          - AWS::S3::Bucket
    DependsOn: 
      - BucketForDeliveryChannel
      - RoleForConfigRecorder

  ConfigDeliveryChannel:
    Type: AWS::Config::DeliveryChannel
    Properties:
      S3BucketName: !Ref BucketForDeliveryChannel
    DependsOn: 
      - BucketForDeliveryChannel
      - RoleForConfigRecorder

```
注意点があり、「レコーダーと配信チャンネルは、同時に作らなければいけない（2つの作成順序に前後の依存を持たせてはいけない）」という点です。

https://www.qes.co.jp/media/aws/a239

依存を持たせると作成が途中で止まったりします。

これで作成するとコンソールの画面も変わります。作成前のTOPは以下でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/b208e73d-79bc-f560-3a8d-27bbb786bdf3.png)

作成後は以下のように、セットアップ後、という形になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/90ddaac0-fb3a-7780-5a67-25f39f1c0d92.png)

ルールを作成するコードは以下になります。今回は「パブリックアクセスブロックがされていないバケットを検知」というルールにしました。
```yaml:
AWSTemplateFormatVersion: 2010-09-09

Resources:
  ConfigRule:
    Type: AWS::Config::ConfigRule
    Properties:
      Source:
        Owner: AWS
        # https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/managed-rules-by-aws-config.html
        SourceIdentifier: S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED
```
ルールは自作もできるのですが、AWSのマネージドルールにパラメータを渡すだけ、が楽です。今回も「S3のパブリックアクセスブロック無効」というテンプレートがあったので、その識別子を利用しています。このテンプレートにはパラメータはありませんので、識別子を指定するだけでした。

テンプレートと識別子は以下にあります。

https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/managed-rules-by-aws-config.html

スタック作成したら即検知されました。先ほど、配信チャンネル用に作成したバケットが検知されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/c59ec957-a35b-2da6-fc65-a5d91ca5c75b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/a894041a-6103-fd31-9c3a-7cfbc5bc0209.png)

# 片付け

スタックを2つ作っただけなので、作成順序と逆に削除していくだけです。
S3は削除ポリシーを保持にしていたので、別途中身を空にして削除してください。

画面もセットアップの段階に戻りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/535f2390-50b9-5ccd-7812-d258d6aea377.png)

# おわりに
今回はAWS Configについて学んだことを記事にしました。
独自の言葉が多くてとっつきにくかったですが、まずレコーダーと配信チャンネルから覚えていけば、理解が進むと思います。
利用している方や、認定に向けての勉強中の方のお力になれれば幸いです。