Account Factory for Terraform (AFT)のコスト削減のために、AFTを使ってAFT管理アカウントのSecurity Hubコントロール「Backup.1」を無効化してみる

2024.02.26

Security Hubコントロール「Backup.1」をAFT管理アカウントだけ無効にしたいことがありました。

Security Hub関連の設定はAFTで管理しているため、AFTで行いました。

Security Hubコントロール「Backup.1」

2023年12月に追加されたコントロールで概要は以下です。

[Backup.1] AWS Backup 復旧ポイントは保管時に暗号化する必要があります

AWS Backup コントロール - AWS Security Hub

なぜSecurity Hubコントロール「Backup.1」をAFT管理アカウントだけ無効化したいか?

AFT管理アカウント内のAWS Backup復旧ポイントがデフォルト設定だと数が多くなるため、Security Hubコントロール「Backup.1」のチェックで、Security HubとConfigのコストが増えるためです。

AFT管理アカウントでは、以下の理由から無効化して問題ないと判断しました。

  • AFTで作成されるバックアップボールトの設定で、AWS Backup復旧ポイントは暗号化されている
  • AFT管理アカウントにはAFT以外のリソースを配置しない(暗号化設定を行うバックアップボールトが増えることはない)

例えば、AFTを2年程度運用すると、AWS Backup復旧ポイントが70,000個(2880(月) * 24(2年) = 69,120)作成されます。

AFTで作成されるAWS Backup復旧ポイントの保持期間はデフォルトで永続になっています。

SecurityHubコントロールBackup.1が有効になっていた場合、280USDのコストがかかります。(SecurityHubは毎月、AWS Configはルールの評価結果が変わったタイミングやAWS・ユーザー起因のConfigルールの再作成のタイミングで課金発生)

  • SecurityHubセキュリティチェック: 70USD/月
  • AWS Config: 210USD/月
    • AWS::config::ResourceCompliance(Configルールの準拠非準拠が記録されるリソース)がセキュリティチェックの回数分記録される
    • 設定項目あたり(連続的な記録) 0.003USD * 70,000(復旧ポイントの数)
    • 料金 - AWS Config | AWS

AFTは4つのDynamoDBテーブルを利用します。それぞれに対して1時間に1回バックアップを実行します。

1ヶ月あたり、2880個(4(テーブル数) * 24(時) * 30(日))のAWS Backupの復旧ポイントが作成されます。

AWS ConfigのAWS::config::ResourceComplianceについては、以下の記事をご確認ください。

ちなみに、先日のアップデートで、AWS Backup復旧ポイントの保持期間をカスタマイズ可能になりました。

保持期間を設定することで、コストカットが見込めます。

保持期間を3ヶ月にすると、35USD/月となり、例示したもの(280USD/月)と比べ245USD/月のコスト削減になります。

  • 35USD/月= (0.001(Security Hubチェック) * 8640(復旧ポイントの数)) + (0.003(Config記録) * 8640(復旧ポイントの数))
    • 8640 =(4(テーブル数) * 24(時) * 30(日) * 3(月)

やってみた

手順は基本的に以下の記事と同様です。

1.アカウントカスタムリポジトリにコードを追加 1.リクエストリポジトリにパラメータを追加(account_customizations_nameを追加) 1.手動でStep Functionsステートマシンを実行

今回は以下の部分が異なります。(ユーザーガイド カスタマイズの再呼び出し相当)

  • 対象アカウント(AFT管理アカウント)は作成済みのアカウントである
  • 対象アカウントはAFTで管理されていない
  • Security Hubのコントロールを無効化する

AFT管理下にアカウントを置く際に、カスタマイズ用のPipelineが実行されます。

そのため、今回は手動でStep Functionsステートマシンを実行する必要はありません。よって、以下の手順になります。(ユーザーガイド アカウントカスタマイズの適用相当)

1.アカウントカスタムリポジトリにコードを追加 2.リクエストリポジトリにパラメータを追加

前提

  • リポジトリ略称や前提は前述の記事と同様です

1. アカウントカスタムリポジトリにコードを追加

アカウントカスタムリポジトリに、ACCOUNT_TEMPLATEディレクトリをコピーしてaft-managementを作成します。

このディレクトリ名は、次の手順で設定するaccount_customizations_nameと同様である必要があります。

aft-managementディレクトリのterraform配下に以下のファイルを作成し配置します。

securityhub.tf

data "aws_caller_identity" "current" {}

resource "aws_securityhub_standards_control" "aws_backup_recovery_points_should_be_encrypted_at_rest" {
  standards_control_arn = "arn:aws:securityhub:ap-northeast-1:${data.aws_caller_identity.current.account_id}:control/aws-foundational-security-best-practices/v/1.0.0/Backup.1"
  control_status  = "DISABLED"
  disabled_reason = "AFT Backup has a large number of recovery points and to reduce costs"
}

ちなみに、standards_control_arnは以下のようにAWS CLIのsecurityhub list-standards-control-associations等で確認可能です。

$ aws securityhub  --region ap-northeast-1 list-standards-control-associations --security-control-id Backup.1

aft-managementディレクトリは以下の構成になります。

$ tree -l aft-management
aft-management
├── api_helpers
│   ├── post-api-helpers.sh
│   ├── pre-api-helpers.sh
│   └── python
│       └── requirements.txt
└── terraform
    ├── aft-providers.jinja
    ├── backend.jinja
    └── securityhub.tf

変更をGitにPushします。

2. リクエストリポジトリにパラメータを追加

既存アカウントをAFTに登録するには、以下の条件があります。

  • AWS アカウントは、AWS Control Tower に登録している必要があります。
  • AWS アカウントは、AWS Control Tower 組織に属している必要があります。

既存のアカウントの更新 - AWS Control Towerから引用

対象アカウントが条件を満たしていることを確認し、リクエストリポジトリにAFT管理アカウントを追加します。

account-requests.tf

# 以下を追加
module "aft_management" {
  source = "./modules/aft-account-request"

  control_tower_parameters = {
    AccountEmail              = "aws+aft-management@example.jp" 
    AccountName               = "aft-management-01"
    ManagedOrganizationalUnit = "AFT-ManagementOU"
    SSOUserEmail              = "aws+master@example.jp" 
    SSOUserFirstName          = "NOT" 
    SSOUserLastName           = "USE" 
  }

  account_tags = {
    "Project"     = "AFT-Management"
    "Environment" = "Production"
    "AFT"         = true
  }

  change_management_parameters = {
    change_requested_by = "sato"
    change_reason       = "Adding existing account to AFT"
  }

  custom_fields = {
    custom1 = "a"
    custom2 = "b"
  }
  account_customizations_name = "aft-management"
}

control_tower_parametersの値は、Service Catalogの情報を使います。

Service Catalogの情報はOrganizations管理アカウント -> AWSマネジメントコンソール -> Service Catalog -> Provisioned -> Provisioned productsの順に選択します。

その後Access FilterAccountに変更すると、アカウント毎の製品が確認できます。

登録したいアカウントを選択して、Outputsの部分を確認します。

登録が終わったら、GitでPushを行います。

Pushをトリガーにパイプラインが起動して、DynamoDBテーブルに上記の内容が登録されます。

それをトリガーにLambdaが起動して、AFT管理アカウント用のCodePipeline作成等が行われます。

マネジメントコンソールを確認すると、CodePipelineが作成されアカウントカスタマイズの処理が実行されたことが分かります。

ステージAFT-Account-Customizationsのログ(View details)を見ると、SecurityHubでコントロールを無効化する変更が行われたことが分かります。

※スクショはstandards_control_arnがAutoScaling.5になっていますが、本来は該当箇所がBackup.1になります