[アップデート]API を使用して AWS Control Tower ランディング ゾーン操作の自動化が可能になりました #AWSreInvent
こんにちは。たかやまです。
いままでControl Towerのランディングゾーンの操作はコンソールからしかできませんでしたが、今回アップデートによりついにControl Towerのランディングゾーンの操作がAPIより可能になりました。
さきにまとめ
- 追加のAPIは以下
- GetLandingZone/ListLandingZones - ランディングゾーンの設定オプションを表示
- CreateLandingZone/UpdateLandingZone/DeleteLandingZone - ランディングゾーンのリソースを管理
- ResetLandingZone - ランディングゾーンのドリフトを修正
- GetLandingZoneOperation - 進行中の変更を監視
- APIの操作からはリージョン拒否コントロールは非対応
- リージョン拒否コントロールを利用する場合にはコンソールから設定を実施する
- CloudFormationにも対応
※ただし、検証時点でAPIまわりの整備がちゃんとされていなかったため後日追記予定
以下のブログで検証してみました。
やってみる
AWS CLI
AWS CLIでやってみようと思ったのですが、アップデート発表時点(11/26)の最新AWS CLI 2.13.38 ではまだ対応していないようでした。
Bump version to 2.13.38 · aws/aws-cli@5c8bec1
ドキュメントとして用意されているので、期待して待ちましょう!
CloudFormation
次にCloudFormationも対応しているとのことで、こちらのシナリオを試してみたいと思います。
シナリオとしては、既存のログアカウントとセキュリティアカウントを使ってランディングゾーンを作成するというものです。そのため事前準備として以下のCloudFormationを実行して各アカウントとControl Tower実行のためのIAMロールを作成します。
Parameters: LoggingAccountEmail: Type: String Description: The email Id for centralized logging account LoggingAccountName: Type: String Description: Name for centralized logging account SecurityAccountEmail: Type: String Description: The email Id for security roles account SecurityAccountName: Type: String Description: Name for security roles account Resources: MyOrganization: Type: 'AWS::Organizations::Organization' Properties: FeatureSet: ALL LoggingAccount: Type: 'AWS::Organizations::Account' Properties: AccountName: !Ref LoggingAccountName Email: !Ref LoggingAccountEmail SecurityAccount: Type: 'AWS::Organizations::Account' Properties: AccountName: !Ref SecurityAccountName Email: !Ref SecurityAccountEmail AWSControlTowerAdmin: Type: 'AWS::IAM::Role' Properties: RoleName: AWSControlTowerAdmin AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: controltower.amazonaws.com Action: 'sts:AssumeRole' Path: '/service-role/' ManagedPolicyArns: - !Sub >- arn:${AWS::Partition}:iam::aws:policy/service-role/AWSControlTowerServiceRolePolicy AWSControlTowerAdminPolicy: Type: 'AWS::IAM::Policy' Properties: PolicyName: AWSControlTowerAdminPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: 'ec2:DescribeAvailabilityZones' Resource: '*' Roles: - !Ref AWSControlTowerAdmin AWSControlTowerRMSPermissions: Type: 'AWS::IAM::Policy' Properties: PolicyName: AWSControlTowerRMSPermissions PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'account:EnableRegion' - 'account:ListRegions' - 'account:GetRegionOptStatus' Resource: '*' Roles: - !Ref AWSControlTowerAdmin AWSControlTowerCloudTrailRole: Type: 'AWS::IAM::Role' Properties: RoleName: AWSControlTowerCloudTrailRole AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: 'sts:AssumeRole' Path: '/service-role/' AWSControlTowerCloudTrailRolePolicy: Type: 'AWS::IAM::Policy' Properties: PolicyName: AWSControlTowerCloudTrailRolePolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: !Sub >- arn:${AWS::Partition}:logs:*:*:log-group:aws-controltower/CloudTrailLogs:* Effect: Allow Roles: - !Ref AWSControlTowerCloudTrailRole Path: '/service-role/' AWSControlTowerConfigAggregatorRoleForOrganizations: Type: 'AWS::IAM::Role' Properties: RoleName: AWSControlTowerConfigAggregatorRoleForOrganizations AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: config.amazonaws.com Action: 'sts:AssumeRole' Path: '/service-role/' ManagedPolicyArns: - !Sub arn:${AWS::Partition}:iam::aws:policy/service-role/AWSConfigRoleForOrganizations AWSControlTowerStackSetRole: Type: 'AWS::IAM::Role' Properties: RoleName: AWSControlTowerStackSetRole AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: cloudformation.amazonaws.com Action: 'sts:AssumeRole' Path: '/service-role/' AWSControlTowerStackSetRolePolicy: Type: 'AWS::IAM::Policy' Properties: PolicyName: AWSControlTowerStackSetRolePolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: 'sts:AssumeRole' Resource: !Sub 'arn:${AWS::Partition}:iam::*:role/AWSControlTowerExecution' Effect: Allow Roles: - !Ref AWSControlTowerStackSetRole Outputs: LogAccountId: Value: Fn::GetAtt: LoggingAccount.AccountId Export: Name: LogAccountId SecurityAccountId: Value: Fn::GetAtt: SecurityAccount.AccountId Export: Name: SecurityAccountId
Prerequisites for launching a landing zone using AWS CloudFormation - AWS Control Tower
次に以下のCloudFormationを実行してランディングゾーンを作成します。
AWSTemplateFormatVersion: "2010-09-09" Parameters: Version: Type: String Default: "1.0.0" Description: The version number of Landing Zone GovernedRegions: Type: CommaDelimitedList Description: List of governed regions SecurityOuName: Type: String Description: The security Organizational Unit name SandboxOuName: Type: String Description: The sandbox Organizational Unit name CentralizedLoggingAccountId: Type: String Description: The AWS account ID for centralized logging SecurityAccountId: Type: String Description: The AWS account ID for security roles LoggingBucketRetentionPeriod: Type: Number Description: Retention period for centralized logging bucket AccessLoggingBucketRetentionPeriod: Type: Number Description: Retention period for access logging bucket Resources: MyLandingZone: Type: AWS::ControlTower::LandingZone Properties: Version: !Ref Version Tags: - Key: "k1" Value: "v1b" - Key: "k3" Value: "v3" Manifest: GovernedRegions: !Join - "," - !Ref GovernedRegions OrganizationStructure: Security: Name: !Ref SecurityOuName Sandbox: Name: !Ref SandboxOuName CentralizedLogging: AccountId: !Ref CentralizedLoggingAccountId Configurations: LoggingBucket: RetentionDays: !Ref LoggingBucketRetentionPeriod AccessLoggingBucket: RetentionDays: !Ref AccessLoggingBucketRetentionPeriod SecurityRoles: AccountId: !Ref SecurityAccountId AccessManagement: Enabled: "false"
Create a new landing zone using AWS CloudFormation - AWS Control Tower
Stack作成の実行コマンドは以下のようになります。
aws cloudformation create-stack --stack-name ControlTower \ --template-body file://controltower.yml \ --parameters \ ParameterKey=Version,ParameterValue=3.2.0 \ ParameterKey=GovernedRegions,ParameterValue=ap-northest-1 \ ParameterKey=SecurityOuName,ParameterValue=Security \ ParameterKey=SandboxOuName,ParameterValue=Sandbox \ ParameterKey=CentralizedLoggingAccountId,ParameterValue=<log-accout-id> \ ParameterKey=SecurityAccountId,ParameterValue=<security-accout-id> \ ParameterKey=LoggingBucketRetentionPeriod,ParameterValue=3 \ ParameterKey=AccessLoggingBucketRetentionPeriod,ParameterValue=3 \ ParameterKey=KMSKey,ParameterValue=arn:aws:kms:ap-northeast-1:<management-accout-id>:key/<key-id>
ただ、作成されたStackは以下のようにFAILEDになってしまいました。
現時点の最新が3.2.0でしたが、エラーメッセージとしてLandingZone version must be latest available version
が返されてしまいました。
(ちなみにパラメータのドキュメントと同じ .0 を抜いた 3.2
を渡すと今度はValidationException
になってしまいました...)
Configuration update management in AWS Control Tower - AWS Control Tower
こちらも執筆時点でCloudFormationのドキュメントが整備されていなかったので後日確認したいと思います。
最後に
いままでランディングゾーンの設定はコンソールをぽちぽちする必要がありましたが、APIから可能になることでより実装の自動化が可能になりました。
まだ、利用できる環境が整備されていなそうですが、近日更新されると思うので期待して待ちたいと思います。
再掲になりますが、以下のブログで検証しています。
以上、たかやま(@nyan_kotaroo)でした。