こんにちは。たかやまです。
いままで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)でした。