はじめに
 Access Analyzerは、外部エンティティと共有されているリソースを検出しますので、意図しない公開設定がないか可視化でき、セキュリティに役立ちます。
 グローバルサービスだと思っていましたがリージョン別サービスだったので、CloudFormationでまとめて有効化を目指します。
 なお、利用は無料です。
Access Analyzer有効化(コンソール)
 右上のリージョン名をご覧いただければ分かる通り、グローバルではなく東京と記載されていることが分かります。
 IAMのコンソールにあるのでグローバルだと思ってしまうかもしれませんが、リージョン別サービスです。
 対象リージョンは現在選択しているリージョンに固定されます。
 アナライザーを作成すると、自動的にサービスにリンクされたロールも作成されます。
 ロールの権限は以下の通りです。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketPublicAccessBlock",
        "s3:GetBucketPolicyStatus",
        "s3:GetAccountPublicAccessBlock",
        "s3:ListAllMyBuckets",
        "s3:GetBucketAcl",
        "s3:GetBucketLocation",
        "s3:GetBucketPolicy",
        "s3:ListAccessPoints",
        "s3:GetAccessPoint",
        "s3:GetAccessPointPolicy",
        "s3:GetAccessPointPolicyStatus",
        "iam:GetRole",
        "iam:ListRoles",
        "kms:DescribeKey",
        "kms:GetKeyPolicy",
        "kms:ListGrants",
        "kms:ListKeyPolicies",
        "kms:ListKeys",
        "ec2:DescribeVpcs",
        "ec2:DescribeVpcEndpoints",
        "ec2:DescribeByoipCidrs",
        "ec2:DescribeAddresses",
        "lambda:ListFunctions",
        "lambda:GetPolicy",
        "lambda:ListLayers",
        "lambda:ListLayerVersions",
        "lambda:GetLayerVersionPolicy",
        "sqs:GetQueueAttributes",
        "sqs:ListQueues",
        "organizations:ListAWSServiceAccessForOrganization",
        "organizations:ListDelegatedAdministrators",
        "organizations:ListRoots",
        "organizations:ListParents",
        "organizations:ListChildren",
        "organizations:ListOrganizationalUnitsForParent",
        "organizations:ListAccountsForParent",
        "organizations:ListAccounts",
        "organizations:DescribeAccount",
        "organizations:DescribeOrganization",
        "organizations:DescribeOrganizationalUnit"
      ],
      "Resource": "*"
    }
  ]
}
 Access Analyzerはリソースベースのポリシーを分析して外部エンティティと共有されているか検出するので、その分析のための権限が付与されていることが分かります。
 Organizationsのアクションは、Access Analyzerの信頼ゾーンが組織にも適用できるので、その関係で必要なアクションであるから許可されているのだと思います。
アナライザーの作成が完了し、外部エンティティと共有しているリソースがあったので検出されました。
 アクションのエクスポートを行うとこのような画面になり、JSON形式でダウンロードできます。
 このリソースは外部エンティティと共有することを想定して作成したリソースなので、アーカイブ済みに移します。
 問題のないリソースをアーカイブ済みに移すことで、問題あるリソースの発見が容易になります。
 アーカイブルールを作成したら、ルールに一致する検出結果が自動的にアーカイブされるようになります。
 作成してみたところ、自動的にアーカイブ済みに移動したことを確認できました。
 今度はCloudFormationで作成します。
Access Analyzer有効化(CloudFormaiton)
 まず一つのリージョンで有効化します。
 テンプレートは以下の通りです。
AWSTemplateFormatVersion: 2010-09-09
Description: EnableAccessAnalyzer
Parameters:
  AccountID:
    Description: Account ID to be archived
    Type: String
    MaxLength: 12
    MinLength: 12
Resources:
  AccessAnalyzer:
    Type: AWS::AccessAnalyzer::Analyzer
    Properties:
      Type: ACCOUNT
      ArchiveRules:
        - Filter:
            - Property: principal.AWS
              Eq:
                - !Ref AccountID
            - Property: isPublic
              Eq:
                - false
          RuleName: ArchiveOfTrustedID
Outputs:
  AccessAnalyzerOutput:
    Value: !Ref AccessAnalyzer
 Access Analyzerの有効化と、指定したアカウントIDと共有するリソースが検出された場合は自動的にアーカイブするアーカイブルールを作成します。
 アーカイブルールの作成は以下の公式ドキュメントとコンソールで作成した際のCloudTrailログ、CLIを参考にしました。
 一番確実なのは、コンソールで自分が作成したいアーカイブルールを作成して、それをCLIで見る方法です。
 https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-reference-filter-keys.html
 なお、Outputsを記載しているのは単に何が出力されるのか気になったので載せているだけです。
 結果はARNが出力されました。
 AWS::AccessAnalyzer::AnalyzerをRef関数に渡すとARNが返されるので当然の結果ですが、普段Outputsを使っていないせいか、すぐにその答えにたどり着きませんでした。
 スタックの作成は成功しました。
 一つのリージョンで無事Access Analyzerを有効化できたので、今度は全リージョンに対して行います。
 まず、スタックセット作成のために、二つのIAMロールを作成します。
 作成は省略しますが、ほぼこちらの公式ドキュメント通りに行っています。
異なる点は、ターゲットアカウント(同じアカウントなのですが)のIAMロールの権限を以下の通り小さくしているところです。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "access-analyzer:CreateArchiveRule",
                "access-analyzer:CreateAnalyzer",
                "cloudformation:*",
                "sns:*"
            ],
            "Resource": "*"
        }
    ]
}
SNSを許可しているのは、スタックセット作成時に以下のようにエラーが出たからです。
 なぜSNSが?と思いましたが、公式ドキュメントでは以下のポリシーがスタックセットが機能するための最低限のポリシーだとしています。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": 
               [
                 "cloudformation:*",
                 "s3:*",
                 "sns:*"
               ],
            "Resource": "*"
        }
      ]
}
 今までこの記載は、スタックセットでS3とSNSを作成していると思っていましたが、勘違いだったようです。
 しかし、ここで疑問なのはS3をポリシーに追加しなくても作成できたことです。
 S3の許可がないと失敗する場合があるのでしょうか。
 よく分からないのでスルーします。
アカウント内のリージョンにデプロイするのにIAMロールを作成するのは少し不思議な感じがしますが、進めていきます。
リージョンはデフォルトで無効になっているリージョン(ケープタウン、香港、バーレーン、ミラノ)以外にします。
 16リージョンでAccess Analyzerを有効化できました。
 コンソールで確認してみます。
 全リージョンで有効化を確認できました。
 いつもは検証が終わったらスタックセットを削除するのですが、Access Analyzerは無料ですので残しておきます。
おわりに
 Access Analyzerは無料で使用できるのが嬉しいですね。
 アーカイブルールの追加・削除もスタックセットで簡単にできそうなので、融通が効きそうです。
 今回は同一アカウント内の全リージョンが対象でしたが、マルチアカウントの全リージョンにも簡単に作成できそうなので、規模が大きくなるほどスタックセットの効果が発揮できそうです。








