Microsoft Defender for Cloud Apps に接続する AWS アカウントの設定を AWS CloudFormation で展開する

Microsoft Defender for Cloud Apps に AWS アカウントを接続するために必要な AWS のリソースを AWS Cloud Formation StackSets を用いて AWS Organizations 全体に展開する方法を紹介します。
2023.06.08

Microsoft 365 Defender の一部である Microsoft Defender for Cloud Apps では、クラウドアプリとして AWS アカウントを接続できます。接続のためには、次のドキュメントに記載されている IAM ユーザーの作成が必要となりますが、AWS Organizations 環境で複数の AWS アカウントがある場合は手間です。そこで、AWS CloudFormation の StackSets を利用して、組織全体に接続に必要なリソースを展開する方法を紹介します。

AWS CloudFormation テンプレート例

次のドキュメントに記載のある通り、AWS 側で必要なリソースは IAM ユーザー(アクセスキー)です。必要な権限の記載もあります。

接続に必要な IAM ユーザーを作成する CloudFormation テンプレートの一例を示します。

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  ProjectName:
    Description: Resource name prefix
    Type: String
    Default: "ms-defender-for-cloud-apps"

Resources:
  IAMUser:
    Type: AWS::IAM::User
    Properties:
      Path: /
      UserName: !Sub ${ProjectName}-user
      Policies:
        - PolicyName: !Sub ${ProjectName}-policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - cloudtrail:DescribeTrails
                  - cloudtrail:LookupEvents
                  - cloudtrail:GetTrailStatus
                  - cloudwatch:Describe*
                  - cloudwatch:Get*
                  - cloudwatch:List*
                  - iam:List*
                  - iam:Get*
                  - s3:ListAllMyBuckets
                  - s3:PutBucketAcl
                  - s3:GetBucketAcl
                  - s3:GetBucketLocation
                Resource: "*"

  IAMUserAccessKey:
    Type: AWS::IAM::AccessKey
    Properties:
      UserName: !Ref IAMUser

  IAMUserSecret:
    Type: AWS::SecretsManager::Secret
    DeletionPolicy: Delete
    UpdateReplacePolicy: Delete
    Properties:
      Name: !Sub ${ProjectName}-credential
      SecretString: !Sub "{\"AccessKey\":\"${IAMUserAccessKey}\",\"SecretAccessKey\":\"${IAMUserAccessKey.SecretAccessKey}\"}"

作成するリソースは IAM ユーザーおよびアクセスキー、AWS Secrets Manager です。

Secrets Manager はシークレットアクセスキーを格納するために利用しています。格納する候補には SSM パラメータストアもありますが、CloudFormation はSecureStringパラメータに対応していなかったため、今回は Secrets Manager を採用しています。

AWS CloudFormation doesn't support creating a SecureString parameter type.

引用元:AWS::SSM::Parameter - AWS CloudFormation


また、アクセスキーを持つ IAM ユーザーを CloudFormation で作成する方法は次のブログでも紹介されています。


上記のテンプレート例ではパラメータとしてリソース名のプリフィックスを指定できるようにしています。パラメータの値をms-defender-for-cloud-appsと指定すると、次のリソース名で作成します。

リソース種別 リソース名
IAM ユーザー ms-defender-for-cloud-apps-user
Secrets Manager シークレットの名前 ms-defender-for-cloud-apps-credential

AWS CloudFormation の展開

AWS Organizations の組織内のアカウントへの展開を AWS CLI で試してみます。

StackSets をサービスマネージドアクセスで利用する場合は管理アカウントを含めることができないため、管理アカウントを対象としたスタックとメンバーアカウントを対象にした StackSets に分けて展開します。


管理アカウントへの展開

AWS CloudShell で設定します。

CloudFormation テンプレートをアップロードして次のコマンドで展開します。アップロードしたテンプレート名はms-defender-cloud-for-apps.yamlです。オプションの値は環境に合わせて適宜修正が必要です。

aws cloudformation create-stack \
  --region ap-northeast-1 \
  --stack-name ms-defender-for-cloud-apps \
  --parameters ParameterKey="ProjectName",ParameterValue="ms-defender-for-cloud-apps" \
  --template-body file://ms-defender-cloud-for-apps.yaml \
  --capabilities CAPABILITY_NAMED_IAM

オプションの詳細は次のドキュメントで確認できます。


実行結果例です。

aws cloudformation create-stack \
>   --region ap-northeast-1 \
>   --stack-name ms-defender-for-cloud-apps \
>   --parameters ParameterKey="ProjectName",ParameterValue="ms-defender-for-cloud-apps" \
>   --template-body file://ms-defender-cloud-for-apps.yaml \
>   --capabilities CAPABILITY_NAMED_IAM
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:130906976736:stack/ms-defender-for-cloud-apps/9d040f90-0547-11ee-9982-06531example"
}

実行状況は次のコマンドで確認します。CREATE_COMPLETEが正常に作成終了したステータスとなります。

$ aws cloudformation describe-stacks --stack-name ms-defender-for-cloud-apps --query 'Stacks[].StackStatus'
[
    "CREATE_COMPLETE"
]


展開後の作成リソース一覧です。

Secrets Manager からアクセスキーとシークレットアクセスキーを確認できます。アクセスキーは IAM 画面から確認できるため、Secrets Manager への格納は必須ではないのですが、Secrets Manager の画面でまとめて確認したかったためアクセスキーも格納しています。


メンバーアカウントへの展開

AWS CloudShell で設定します。

次のコマンドで展開します。CloudFormation テンプレートは「管理アカウントへの展開」時に利用したテンプレートと同じファイルです。オプションの値は環境に合わせて適宜修正が必要です。次の例ではルート OU を指定して展開先は組織全体としています。また、展開先リージョンは東京リージョンを指定しています。IAM はグローバルサービスであるため、全リージョンで作成する必要がないためです。

StackSets の作成

aws cloudformation create-stack-set \
  --region ap-northeast-1 \
  --stack-set-name ms-defender-for-cloud-apps \
  --template-body file://ms-defender-cloud-for-apps.yaml \
  --parameters ParameterKey="ProjectName",ParameterValue="ms-defender-for-cloud-apps" \
  --permission-model SERVICE_MANAGED \
  --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
  --capabilities CAPABILITY_NAMED_IAM

スタックインスタンスの作成

aws cloudformation create-stack-instances \
  --region ap-northeast-1 \
  --stack-set-name ms-defender-for-cloud-apps \
  --deployment-targets OrganizationalUnitIds="r-abcd" \
  --regions ap-northeast-1 \
  --operation-preferences FailureToleranceCount=0,MaxConcurrentCount=1

マネジメントコンソールから設定する場合は、一連の作業で StackSets とスタックインスタンスの両方を作成しますが、AWS CLI の場合はコマンドが別れています。

コマンドとオプションの詳細は次のドキュメントで確認できます。


実行結果例です。

$ aws cloudformation create-stack-set \
>   --region ap-northeast-1 \
>   --stack-set-name ms-defender-for-cloud-apps \
>   --template-body file://ms-defender-cloud-for-apps.yaml \
>   --parameters ParameterKey="ProjectName",ParameterValue="ms-defender-for-cloud-apps" \
>   --permission-model SERVICE_MANAGED \
>   --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
>   --capabilities CAPABILITY_NAMED_IAM
{
    "StackSetId": "ms-defender-for-cloud-apps:698c3f27-43cf-4431-9553-ea69cexample"
}
$ aws cloudformation create-stack-instances \
>   --region ap-northeast-1 \
>   --stack-set-name ms-defender-for-cloud-apps \
>   --deployment-targets OrganizationalUnitIds="r-abcd" \
>   --regions ap-northeast-1 \
>   --operation-preferences FailureToleranceCount=0,MaxConcurrentCount=1
{
    "OperationId": "ab34090a-5268-4a56-804c-12200example"
}

オペレーションの実行状況は次のコマンドで確認できます。operation-idは上記の実行結果例の値を指定する必要があります。SUCCEEDEDが処理が終了したステータスとなります。

$ aws cloudformation describe-stack-set-operation --stack-set-name ms-defender-for-cloud-apps --operation-id ab34090a-5268-4a56-804c-12200example --query 'StackSetOperation.Status'
"SUCCEEDED"


展開後のスタックインスタンス一覧画面です。

「管理アカウントへの展開」のときと同様に各 AWS アカウントの Secrets Manager にアクセスキーとシークレットキーが格納されています。


Microsoft Defender for Cloud Apps のクラウドアプリ設定

各 AWS アカウントのアクセスキーとシークレットアクセスキー情報を用いて、Microsoft Defender for Cloud Apps 側でクラウドアプリとして追加します。

設定は Microsoft 365 Defender ポータル で実行し、次のドキュメントに手順が記載されています。

接続を試しているブログもあり、参考になります。


クラウドアプリ追加後は、状態が接続済みになることを確認できました。

以上で終わりです。

さいごに

Microsoft Defender for Cloud Apps に AWS アカウントを接続するために必要な AWS のリソースを AWS Cloud Formation StackSets を用いて AWS Organizations 全体に展開する方法を紹介しました。AWS アカウントの数が多いと 1 つずつ作業するのが手間なため、StackSets を利用することで効率化できます。

以上、このブログがどなたかのご参考になれば幸いです。