Invoke tagging discipline across organization in AWS - 2

<!-- # Invoke tagging discipline across organization in AWS - 2 -->
![haniwa2_tag_green.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486518/63ba14d7-9eee-86ee-a3d4-35f1f90c0f7e.png)

[前回](https://qiita.com/o2346/items/532571e8b8fcd8dcb53c) の続きです。今回は、特定のリソースタイプに全般的に指定のタグが付与されていないといけない、というルールを施行します。
このルールについては、 AWS Config の [マネージドルール](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/managed-rules-by-aws-config.html) [required-tags](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/required-tags.html) を併用したらどうかと思いついた、ということでした。

すなわち、required-tags によってあるリソースタイプにタグ付けが網羅されているかどうかを、 Tag policies でそれらのタグの Values がルールに沿った値かどうかを、それぞれ監査しようというわけです。
そして前回にも述べたとおり、目的は非準拠の **検知** なのであって、 **遮断ではない** ことに留意。

さて、マネージドルールをただ単一のアカウントに適用するのは容易なことです。しかしこれを cross-account cross-region に展開するのが今回の課題となります。当然ですがいちアカウントいちリージョン、人の温かみのある手でポチポチなど御免です。かといって自作のツールや CloudFormation テンプレートなどもできなくはないが面倒（:point_left:いっつもこれだ笑）

兎に角、なんかもっといい方法は無いのでしょうか？ [あるんですねこれが](https://github.com/awslabs/aws-config-rdk) 。 [ドキュメント](https://rdk.readthedocs.io/en/latest/introduction.html) もよく整備されている模様。いいんじゃないでしょうか

そして次の記事で、より詳細な導入体験が紹介されています
[how-to-develop-custom-aws-config-rules-using-the-rule-development-kit](https://aws.amazon.com/blogs/mt/how-to-develop-custom-aws-config-rules-using-the-rule-development-kit/)
[aws-config-rdk-multi-account-and-multi-region-deployment](https://aws.amazon.com/blogs/mt/aws-config-rdk-multi-account-and-multi-region-deployment/)

前者でまず単一のアカウントを対象とする利用方法を、後者で肝心の組織横断してゆきます。

## やってみる

*注: 基本的に前掲の2つの記事を順に追っていきますが、当記事の肥大化防止と自環境の前提条件を優先し、完全に踏襲はしませんのでご了承下さい。*

### ■ [how-to-develop-custom-aws-config-rules-using-the-rule-development-kit](https://aws.amazon.com/blogs/mt/how-to-develop-custom-aws-config-rules-using-the-rule-development-kit/)

ここではまず単一のアカウント、単一のリージョンで rdk に習熟します

#### Prerequisites

適当な検証用アカウントを選定し、指定された権限を与えられた IAM Role/User または [SSO permission sets](https://docs.aws.amazon.com/ja_jp/singlesignon/latest/userguide/permissionsetsconcept.html) を設定しましょう

`pip install rdk`

#### Workflow

##### Set credentials

先ほどの権限で CLI を実行できるよう [クレデンシャル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-quickstart.html) を取得

##### Initialize

`rdk init`

ローカルに作業ディレクトリを作成する。同時にアカウント側の状況を検査している模様

##### Create or modify

ここは元記事と異なり、 `MyTestRule` のかわりに managed rule `required-tags` を create します

```
rdk create required-tags --resource-types AWS::EC2::Instance,AWS::RDS::DBInstance,AWS::DynamoDB::Table --input-parameters '{"tag1Key":"mycompany:is-sensitive"}' --source-identifier REQUIRED_TAGS
```

- タグの定義は一例に過ぎませんが、 ec2 または rds インスタンス及び DynamoDB Table に該当するリソースタイプの場合、 sensitive な情報の有無の識別として、そういうタグをつけなさいというルールのつもりです
  - Key しか指定していませんが、 Value のほうは Tag Policies のほうで監査しますので、ここでは指定しないことにしています(真偽値を想定しています)
- `mycompany` の部分は自社または自組織の固有名詞に置き換えると良いでしょう
- この時点ではローカルに定義されるだけでアカウントへの反映はまだです

##### Edit (省略)

##### Deploy

```
% rdk deploy required-tags
Found Managed Rule.
Creating CloudFormation Stack for required-tags
Waiting for CloudFormation stack operation to complete...
Waiting for CloudFormation stack operation to complete...
CloudFormation stack operation complete.
Config deploy complete.
```

[マネジメントコンソールでも確認](https://console.aws.amazon.com/config/home?region=us-east-1&awsc-custsat-override=promptUser#/rules/rule-details/required-tags) しましょう(リンク先はus-east-1です)
出力内容の通り、 CloudFormation で展開されています

##### Monitor(省略)

##### 後始末

```
% rdk undeploy required-tags
Delete specified Rules and Lamdba Functions from your AWS Account? (y/N): y
Running un-deploy!
Rule removal initiated. Waiting for Stack Deletion to complete.
Waiting for CloudFormation stack operation to complete...
Waiting for CloudFormation stack operation to complete...
CloudFormation stack operation complete.
Rule removal complete, but local files have been preserved.
To re-deploy, use the 'deploy' command.
%
```

### ■  [aws-config-rdk-multi-account-and-multi-region-deployment](https://aws.amazon.com/blogs/mt/aws-config-rdk-multi-account-and-multi-region-deployment/)

前の記事をモノにしたら、次は肝心の組織横断です。監査専用アカウント(以下元記事にならい、Compliance account)で作業していきます。被監査アカウントの方は Satellite Account(s) または Source Account(s) とします

#### Prerequisite

credentials を取得し、 CLI を使用できるようにする

#### Update the AWS Config rule(省略)

#### Deploy the AWS Config Lambda function

```
% rdk deploy required-tags -f
Running deploy!
Generating CloudFormation template for Lambda Functions!
No IAM role provided, creating a new IAM role for lambda function
Skipping Managed Rule.
Skipping code packaging for Managed Rule.
Updating CloudFormation Stack for Lambda functions.
No changes to Config Rule configurations.
Skipping Lambda upload for Managed Rule.
%
```

managed rule だからか、 role だけが生成される模様（これも省略してよい？）

#### Prepare for cross-account deployment

`rdk create-rule-template required-tags -o required-tags-for-stackset.json --rules-only`

ここで重要な注意点があります。 `--rules-only` オプションに注目して下さい。これは、元記事のコマンド実行例にはありませんが、同じ記事で次のようなことを言っています

> Create-rule-template command – This command generates a CloudFormation template that defines the AWS Config rules themselves. The template also deploys the AWS Config role, AWS Config data bucket, configuration recorder, and delivery channel necessary for the AWS Config rules to work in multiple AWS accounts where the AWS Config rules need to be evaluated against AWS resources. **If you have an existing AWS Config environment set up and you only want to deploy the AWS Config rules, use the ‘—rules-only’ flag.**

**当組織の場合** 、この最後の一文が該当します。つまり私どもの organization で、required-tags を展開する予定の Satellite accounts においては、 AWS Config は既に有効化させているんです。

- もうすこし補足しますとここで Satellite accounts と位置づけている個体群には、以前、 [こちら](https://qiita.com/o2346/items/cd605e9251e234090997) の前提条件として、 [これ](https://github.com/awslabs/aws-securityhub-multiaccount-scripts) で Security Hub の有効化を実施していました。じつはこの過程に AWS Config の有効化も含まれていたのですよ。ちょうど [ここ](https://github.com/awslabs/aws-securityhub-multiaccount-scripts/blob/master/enablesecurityhub.py#L316) のあたりでしょう。
  - よって AWS Config を新規に有効化させる工程は必要ないのであり、逆に次工程の CloudFormation で、無駄な有効化処理が試みられて失敗するのを抑止するために、 `--rules-only` は付けなければならないという次第です

#### Deploy into satellite accounts

> Deploy the generated CloudFormation template into the desired remote satellite accounts. In this walkthrough I’ll deploy the template manually through the AWS Management Console, but you can use any of the available options to deploy the template including the CLI, as an AWS CodePipeline task, using **StackSets**, or using your existing CI/CD pipelines

とのことです。元記事ではある Satellite account にマネジメントコンソール上からやっていますが、これにたいし当組織では [StackSets](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-orgs-enable-trusted-access.html) で、任意の [**OU** に対して展開する](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-getting-started-create.html#stacksets-orgs-associate-stackset-with-org) のが最適と判断し、そうすることにしました
前工程で、 `required-tags-for-stackset.json` というファイル名を出力先として指定し、実行していました。カレントディレクトリにこのファイルができていますがこれは CloudFormation template です。あとはこれをそのまま StackSets のテンプレートとして指定すればよい。
OU(Organizational Unit) にたいして適用しますので当組織の場合、作業現場となるアカウントは Compliance account でも Satellite accounts でもなく **[Organizations の Master Account](https://aws.amazon.com/blogs/aws/new-use-aws-cloudformation-stacksets-for-multiple-accounts-in-an-aws-organization/) となります**

展開が成功し、required-tags の Compliance 状況も確認できたら、一段落です

#### Create a central dashboard

前工程までで Config rule の組織横断展開は成功しました。だがこのままでは各ソースアカウントに準拠情報を見に行かなければならず、中央集約ができておりません。Tag policies のほうではとくに苦労もなく同等の情報は [参照できるようになっている](https://aws.amazon.com/blogs/aws/new-use-tag-policies-to-manage-tags-across-multiple-aws-accounts/) のですが、今やってるのは AWS Config rule ですのでね。
じゃどうすればいいのかというと、 [Aggregated View](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/aggregate-data.html) というのがあります。Compliance account に Satellite accounts の情報を aggregate (集約) するもの。これを利用可能にしましょう

元記事ではマネジメントコンソール上でのやり方です。当記事では CLI/CloudFormation でチャレンジします
このために [ツール](https://github.com/o2346/tagging-discipline/tree/main/configservice) を作成しました
そういえば最近、調査とか検証とかの業務が多かったため、スクリプトをあまり書いてませんでしたね(:point_left:さっき面倒くさいとか言ってなかったか笑)

ともかく、マスターアカウントのクレデンシャルを取得し、[このように](https://github.com/o2346/tagging-discipline/tree/main/configservice#usage-example-to-deploy-a-managed-rule-required-tags-across-organizations-along-with-aggregation-feature-by-cloudformation-stacksets-in-cli) 実行します

できました。

![aggregated-noncompliant-required-tags.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486518/7ce48e49-a8db-7dd7-4ed1-68b04ef8a4aa.jpeg)

Compliance account の画面です。 Satellite account の ap-northeast-1 で required-tags に非準拠事案が発生しているのが報告されています。詳細に飛ぶとリソースタイプ,ID が表示され、特定できます。この場合、検証用にわざと非準拠状態とした ec2 インスタンス だということがわかりました。つまり OK

またこの画像には収まりませんでしたが、下の方にスクロールすると us-east-1 でも同様の報告がされています。 aggregate 成功です:smile:

#### Further enhancement(省略)

## 次の課題

ここまでで Config rule `required-tags` の展開と集約を組織横断的にできたことになります。マネジメントコンソールで温かく aggregated view を見張っていれば準拠情報も俯瞰できるようになりました。けれどもよくよく思い返してみれば、「非準拠事案を抽出し、 Slack channel に集約するのが理想」と [掲げていたはず](https://qiita.com/o2346/items/532571e8b8fcd8dcb53c#%E8%87%AA%E7%B5%84%E7%B9%94%E3%81%AB%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E5%B0%8E%E5%85%A5%E3%81%97%E3%81%A6%E3%81%84%E3%81%8F%E3%81%8B) ですよね。aggregated view を眺めるのがゴールではないのです。するとなんらかの方法で aggregator から非準拠情報を抽出、通知する仕組みを構成する必要があるということになりますが、どうしたものでしょうか。

そういえばこの Compliance account は、[Security Hub の集約先にもして](https://qiita.com/o2346/items/cd605e9251e234090997) おり、 AWS Chatbot による通知系ももう作ってました。それにうまく便乗できると楽なのですが。しかしながらこの案は却下となってしまいます。 [次回](https://qiita.com/o2346/items/e8a1a719ad6d95baebe5) に続きます