適合パック(Conformance Packs)を使って組織内のアカウントにConfigルールと修復アクションを展開してみた

2022.04.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS Config 適合パック(Conformance Packs)のOrganizations統合で、どうやって修復アクションを含めたConfigルールを展開するのか気になったので試してみました。

手順としては以下を参考に実施しています。

適合パック(Conformance Packs)について詳しく知りたい方は、とっっても分かりやすい以下ブログをご参照ください。

前提条件

  • 全アカウントの展開先リージョンでConfigが有効化されていること
  • Organizationsが有効化されていること

やってみる

現在(2022/04/13)ではAWS Config適合パックを使った組織内への展開はコンソールが提供されていないため、CLIから実施します。本ブログでは全てCloudShellから実施します。

実装イメージはこんな感じです。(見づらいので省略していますが、適合パックのConfigルールと修復アクションは管理アカウントとAuditアカウントにも展開されます。)

今回はメンバーアカウントに暗号化されていないS3バケット作成して、修復アクションによって修復されることを確認します。

管理者の委任

まず適合パックを展開する前に、管理者を管理アカウントからAuditアカウントへ委任します。

管理アカウントのCloudShellで以下のコマンドを実行して、Organizationsと連携したConformance Packsのマルチアカウント展開機能を有効化します。

$ aws organizations enable-aws-service-access --service-principal=config-multiaccountsetup.amazonaws.com

次に以下コマンドで管理者の委任をします。{Audit-Account-ID}は委任先のアカウントIDへ置き換えてください。

$ aws organizations register-delegated-administrator --service-principal=config-multiaccountsetup.amazonaws.com --account-id="{Audit-Account-ID}"

正常に委任されているかを以下コマンドで確認します。

$ aws organizations list-delegated-administrators --service-principal=config-multiaccountsetup.amazonaws.com
{
    "DelegatedAdministrators": [
        {
            "Id": "{Audit-Account-ID}",
            "Arn": "arn:aws:organizations::{management-account-id}:account/{org-id}/{Audit-Account-ID}",
            "Email": "{delegated-admin-email}",
            "Name": "child",
            "Status": "ACTIVE",
            "JoinedMethod": "INVITED",
            "JoinedTimestamp": "2020-03-05T11:23:21.521000-08:00",
            "DelegationEnabledDate": "2020-05-20T12:42:17.683000-07:00"
        }
    ]
}

これで管理者の委任は完了です。

修復アクション用IAMロールの展開

Configルールの修復アクションを実行するために、事前にIAMロールをメンバーアカウントに作成する必要があります。

StackSetsを使って以下テンプレートを全アカウントへ展開しておきます。

AWSTemplateFormatVersion: 2010-09-09
Description: Create IAM Role for S3 Operation Automation
Resources:
  S3OperationsAutomationsExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ssm.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      RoleName: "S3OperationsAutomationsExecutionRole"
  S3OperationsAutomationsPolicy:
    DependsOn: S3OperationsAutomationsExecutionRole
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: S3OperationsAutomationsExecutionPolicy
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - s3:PutEncryptionConfiguration
              - s3:GetEncryptionConfiguration
              - s3:ListBucket
              - s3:GetBucketAcl
            Resource:
              - "*"
      Roles:
        - !Ref S3OperationsAutomationsExecutionRole

管理アカウントのCloudFormation>StackSetsを開き、サービスマネージドアクセス許可を選択します。テンプレートをアップロードして東京リージョンを指定して作成します。デプロイターゲットはOU単位ではなく組織へのデプロイを選択しましょう。

他の設定はデフォルトのままで大丈夫です。

適合パックのデプロイ

ここからは委任先のアカウントで実施します。

展開する適合パックは以下テンプレートを利用します。S3バケットが暗号化されていない場合、自動で修復するアクションを設定するテンプレートです。S3BucketServerSideEncryptionEnabled.ymlとして保存します。

{Audit-Account-ID}は委任先アカウントのIDに置き換えてください。(もし委任せず管理アカウントから実行する場合は、管理アカウントのIDに置き換え)

AWSTemplateFormatVersion: 2010-09-09
Description: Enable AWS Config S3 Conformance Pack

Resources:
  S3BucketServerSideEncryptionEnabled:
    Type: "AWS::Config::ConfigRule"
    Properties:
      ConfigRuleName: S3BucketServerSideEncryptionEnabled
      Description: "Checks that your Amazon S3 bucket either has S3 default encryption enabled or that the S3 bucket policy explicitly denies put-object requests without server side encryption."
      Scope:
        ComplianceResourceTypes:
          - "AWS::S3::Bucket"
      Source:
        Owner: AWS
        SourceIdentifier: S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED
  S3BucketServerSideEncryptionEnabledRemediation:
    DependsOn: S3BucketServerSideEncryptionEnabled
    Type: "AWS::Config::RemediationConfiguration"
    Properties:
      ConfigRuleName: S3BucketServerSideEncryptionEnabled
      ResourceType: "AWS::S3::Bucket"
      TargetId: "AWS-EnableS3BucketEncryption"
      TargetType: "SSM_DOCUMENT"
      TargetVersion: "1"
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - arn:aws:iam::{Audit-Account-ID}:role/S3OperationsAutomationsExecutionRole
        BucketName:
          ResourceValue:
            Value: "RESOURCE_ID"
        SSEAlgorithm:
          StaticValue:
            Values:
              - "AES256"
      ExecutionControls:
        SsmControls:
          ConcurrentExecutionRatePercentage: 10
          ErrorPercentage: 10
      Automatic: True
      MaximumAutomaticAttempts: 10
      RetryAttemptSeconds: 600

このファイルをCloudShellへアップロードします。Actions からUpload fileを選択してアップロードしてください。

以下コマンドで適合パックを展開します。パラメータとして適合パックの名前と使用するテンプレートのパスを指定します。更新したい場合も同じコマンドで実行します。

今回は東京リージョンのみでデプロイしていますが、複数リージョンに展開したい場合はリージョンごとに実施して下さい。

$ aws configservice put-organization-conformance-pack --organization-conformance-pack-name="OrgS3ConformancePack" --template-body="file://S3BucketServerSideEncryptionEnabled.yml"
{
    "OrganizationConformancePackArn": "arn:aws:config:ap-northeast-1:{Audit-Account-ID}:organization-conformance-pack/OrgS3ConformancePack-y5jl5kxi"
}

以下状態を確認するコマンドを紹介しておきます。利用する際は適合パックの名前OrgS3ConformancePackを適宜変更して下さい。

デプロイした適合パックを確認するコマンド

$ aws configservice describe-organization-conformance-packs --organization-conformance-pack-name=OrgS3ConformancePack
{
    "OrganizationConformancePacks": [
        {
            "OrganizationConformancePackName": "OrgS3ConformancePack",
            "OrganizationConformancePackArn": "arn:aws:config:ap-northeast-1:{Audit-Account-ID}:organization-conformance-pack/OrgS3ConformancePack-y5jl5kxi",
            "ConformancePackInputParameters": [],
            "ExcludedAccounts": [],
            "LastUpdateTime": "2022-04-13T04:29:47.779000+00:00"
        }
    ]
}

デプロイ状況について確認するコマンド

$ aws configservice describe-organization-conformance-pack-statuses --organization-conformance-pack-name=OrgS3ConformancePack
{
    "OrganizationConformancePackStatuses": [
        {
            "OrganizationConformancePackName": "OrgS3ConformancePack",
            "Status": "CREATE_IN_PROGRESS",
            "LastUpdateTime": "2022-04-13T04:29:47.789000+00:00"
        }
    ]
}

デプロイ状況をアカウント個別に確認するコマンド

$ aws configservice get-organization-conformance-pack-detailed-status --organization-conformance-pack-name=OrgS3ConformancePack
{
    "OrganizationConformancePackDetailedStatuses": [
        {
            "AccountId": "111111111111",
            "ConformancePackName": "OrgConformsPack-OrgS3ConformancePack-y5jl5kxi",
            "Status": "CREATE_SUCCESSFUL",
            "LastUpdateTime": "2022-04-13T04:31:53.898000+00:00"
        },
        {
            "AccountId": "222222222222",
            "ConformancePackName": "OrgConformsPack-OrgS3ConformancePack-y5jl5kxi",
            "Status": "CREATE_SUCCESSFUL",
            "LastUpdateTime": "2022-04-13T04:33:59.835000+00:00"
        }
    ]
}

ステータスがCREATE_SUCCESSFULになればデプロイ完了です。この後は展開したConfigルールと修復アクションの動作確認を行なっていきます。

メンバーアカウントで動作確認

実際にデプロイできたのか確認してみます。メンバーアカウントへログインし、Configの適合パックを確認すると、Auditアカウントから展開した適合パックが表示されています。

展開したConfigルールに設定した修復アクションを確認してみると、塗りつぶしているアカウントIDが自動でメンバーアカウントのIDに置き換わっていました。

以下AutomationAssumeRoleを定義している適合パックのテンプレートの抜粋です。実行元のアカウントID(今回は委任先のアカウントID)を指定すると、自動でメンバーアカウントのアカウントIDに置き換わるようです。

        AutomationAssumeRole:
          StaticValue:
            Values:
              - arn:aws:iam::{Audit-Account-ID}:role/S3OperationsAutomationsExecutionRole

自動修復されるか確認してみる

実際にConfigが非準拠となったとき、自動修復されるか確認してみます。適当なS3バケットのデフォルト暗号化を無効にして作成してみました。

数分待つと、Configルールから非準拠のリソースとして確認できました。しばらく待つとステータスにアクションが正常に実行されましたと表示されれば修復アクションが実行されています。

実際にS3バケットを確認してみると、デフォルト暗号化が有効になっていました。

新規アカウント発行時の動作確認

既存アカウントへの展開は確認できたので、新規アカウントを発行した際の挙動についても確認してみました。

気になったのは、StackSetsでデプロイするAutomation用のロールが適合パックのデプロイ前に作成されるのか?という点です。(もし適合パックが先にデプロイされてしまうと、修復アクションとIAMロールの紐づけでエラーとなる懸念があるため)

ドキュメントには以下の記載がありましたが、既存アカウントへのデプロイに限った記載にも見えます。

PutOrganizationConformancePackを呼び出す前に、すべてのアカウントでこのロールを作成する必要があります。このロールを手動で作成することも、AWS CloudFormation スタックセットを使用してすべてのアカウントでこのロールを作成することもできます。

参考:組織コンフォーマンスパックの前提条件

検証ではControl Towerを利用している環境だったのでアカウントファクトリーからアカウントを発行してみました。

結果としては正常に適合パックがデプロイされ、修復アクションの設定でもエラーは出ていませんでした。おそらくですがStackSets→適合パックの順でデプロイされるため、問題なく修復アクションを作成できそうです。

環境のクリーンアップ

適合パックを削除したい場合は以下コマンドを委任先のアカウントで実行しましょう。

$ aws configservice delete-organization-conformance-pack --organization-conformance-pack-name "OrgS3ConformancePack"

委任の取り消しをする場合は、管理アカウントから以下を実行します。

$ aws organizations deregister-delegated-administrator --account-id="{Audit-Account-ID}" --service-principal=config-multiaccountsetup.amazonaws.com

実行したら以下で委任されたアカウントの有無を確認できます。

$ aws organizations list-delegated-administrators

空のリストが返ってこれば委任の取り消しができています。

Conformance Packsのマルチアカウント展開の機能を利用しない場合は、これも無効化しましょう。

$ aws organizations disable-aws-service-access --service-principal=config-multiaccountsetup.amazonaws.com

あとはAutomation用ロールを展開したStackSetsを削除すればクリーンアップは完了です。

注意点

適合パックのOrganizations連携を試してみて、いくつか注意が必要だなと思ったことを記載しておきます。

  • デプロイ対象は組織内の全アカウントが対象となる(OU単位では選べない)
  • 修復アクションを合わせて展開する場合は、事前に実行するロールをStackSets等で展開しておく必要がある
  • 適合パックのAutomationAssumeRoleで指定するIAM RoleのArnは展開元アカウントIDを指定する
    • 指定を間違うとデプロイで以下のエラーが発生するため注意
    • An error occurred (AccessDeniedException) when calling the PutOrganizationConformancePack operation: Cross-account pass role is not allowed.

おわりに

適合パックを使って組織内のアカウントにConfigルールと修復アクションを展開してみました。ガードレールとして全アカウント共通で設定したいConfigルール(修復アクション)が複数あり、まとめて管理したい場合は非常に便利な機能だと感じました。

逆にそれほど管理するルールの数が多くない場合は、適合パックではなく直接StackSetsでConfigルール個別で展開してしまう方がシンプルかもしれません。利用する環境に合わせて採用を検討してみてください。

参考