Skip to content

Commit b783028

Browse files
committed
Added update logic to the common register delegated admin solution.
Updated README files
1 parent 4eb3507 commit b783028

File tree

4 files changed

+163
-19
lines changed

4 files changed

+163
-19
lines changed

solutions/common/register-delegated-administrator/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ The services that support a delegated administrator account can be configured an
118118

119119
# Implementation Instructions
120120

121+
### [AWS Control Tower](./aws-control-tower)
122+
### CloudFormation StackSets
123+
121124
1. Create new or use an existing S3 bucket within the deployment region owned by the Organization Management Account
122125
* Example bucket name: lambda-zips-[Management Account ID]-[AWS region]
123126
* [Example CloudFormation Template](../../../extras/lambda-s3-buckets.yaml)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: CC-BY-SA-4.0
2+
3+
----
4+
5+
# Implementation Instructions
6+
7+
1. Make sure the required [prerequisites](../../../../extras/aws-control-tower/prerequisites/README.md) are completed
8+
2. Package and upload the common-register-delegated-administrator Lambda function
9+
```shell
10+
export AWS_ACCESS_KEY_ID=INSERT_AWS_ACCESS_KEY_ID
11+
export AWS_SECRET_ACCESS_KEY=INSERT_AWS_SECRET_ACCESS_KEY
12+
export AWS_SESSION_TOKEN=INSERT_AWS_SESSION_TOKEN
13+
14+
export BUCKET=lambda-zips-CHANGE_ME_ACCOUNT_ID-CHANGE_ME_REGION
15+
sh ~/aws-security-reference-architecture-examples/extras/packaging-scripts/package-lambda.sh \
16+
--file_name common-register-delegated-admin.zip \
17+
--bucket $BUCKET \
18+
--src_dir ~/aws-security-reference-architecture-examples/solutions/common/register-delegated-admninistrator/code/src
19+
```
20+
3. Copy the files to the Customizations for AWS Control Tower configuration
21+
1. customizations-for-control-tower-configuration
22+
1. [manifest.yaml](manifest.yaml) -> manifest.yaml
23+
2. [common/register-delegated-administrator/aws-control-tower/parameters/common-register-delegated-administrator.json](../../../common/register-delegated-administrator/aws-control-tower/parameters/common-register-delegated-administrator.json)
24+
-> parameters/common-register-delegated-administrator.json
25+
3. [common/register-delegated-administrator/templates/common-register-delegated-administrator.yaml](../../../common/register-delegated-administrator/templates/common-register-delegated-administrator.yaml)
26+
-> templates/common-register-delegated-administrator.yaml
27+
4. Add service principals to the pServicePrincipalList parameter in the
28+
parameters/common-register-delegated-administrator.json
29+
5. Add the [common/register-delegated-administrator/aws-control-tower/manifest.yaml](../../../common/register-delegated-administrator/aws-control-tower)
30+
resource configuration to your manifest.yaml file.
31+
```yaml
32+
...
33+
cloudformation_resources:
34+
# -----------------------------------------------------------------------------
35+
# Common Register Delegated Administrator
36+
# -----------------------------------------------------------------------------
37+
- name: CommonRegisterDelegatedAdmin
38+
template_file: templates/common-register-delegated-administrator.yaml
39+
parameter_file: parameters/common-register-delegated-administrator.json
40+
deploy_method: stack_set
41+
deploy_to_account:
42+
- REPLACE_ME_ORG_MANAGEMENT_ACCOUNT_NAME
43+
...
44+
```
45+
6. Update the manifest.yaml file with your account names and SSM parameters
46+
7. Deploy the Customizations for AWS Control Tower configuration
47+
8. How to verify after the pipeline completes?
48+
1. Export the management account credentials in your local terminal and run the following script:
49+
```shell
50+
for accountId in $(aws organizations list-delegated-administrators --query 'DelegatedAdministrators[*].Id' \
51+
--output text); do echo -e "$accountId\n Service Principals: " \
52+
$(aws organizations list-delegated-services-for-account --account-id $accountId \
53+
--query 'DelegatedServices[*].ServicePrincipal'); done
54+
```
55+
2. Verify that the service principals are listed for the delegated administrator account
56+
57+
# Delete Instructions
58+
59+
1. Verify that all solutions related to the service principals are removed before deleting the solution
60+
2. Within the Customizations for AWS Control Tower configuration
61+
1. Remove the Common Register Delegated Administrator configuration from the manifest.yaml file
62+
2. (Optional) Delete the parameter and template files for the Common Register Delegated Administrator solution
63+
3. Deploy the Customizations for AWS Control Tower configuration
64+
4. After the pipeline completes, log into the Management account and navigate to the CloudFormation StackSet page
65+
1. Delete the Stack Instance from the CustomControlTower-CommonRegisterDelegatedAdmin CloudFormation StackSet
66+
2. After the Stack Instance deletes, delete the CustomControlTower-CommonRegisterDelegatedAdmin CloudFormation
67+
StackSet
68+

solutions/common/register-delegated-administrator/code/src/app.py

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ def register_delegated_administrator(account_id: str, service_principal: str):
8282

8383
try:
8484
# Register the delegated administrator
85-
ORGANIZATIONS_CLIENT.register_delegated_administrator(AccountId=account_id, ServicePrincipal=service_principal)
85+
ORGANIZATIONS_CLIENT.register_delegated_administrator(AccountId=account_id,
86+
ServicePrincipal=service_principal)
87+
8688
# Get the delegated administrators
8789
delegated_administrators = ORGANIZATIONS_CLIENT.list_delegated_administrators(
8890
ServicePrincipal=service_principal)
@@ -91,7 +93,9 @@ def register_delegated_administrator(account_id: str, service_principal: str):
9193
if not delegated_administrators:
9294
logger.info(f"The delegated administrator {service_principal} was not registered")
9395
raise ValueError("Error registering the delegated administrator account")
94-
except ClientError as error:
96+
except ORGANIZATIONS_CLIENT.exceptions.AccountAlreadyRegisteredException:
97+
logger.debug(f"Account: {account_id} already registered for {service_principal}")
98+
except Exception as error:
9599
logger.error(f"register_delegated_administrator error: {error}")
96100
raise ValueError("Error registering the delegated administrator account")
97101

@@ -117,8 +121,9 @@ def deregister_delegated_administrator(account_id: str, service_principal: str):
117121

118122
if not delegated_administrators:
119123
logger.info(f"The deregister was successful for the {service_principal} delegated administrator")
120-
121-
except ClientError as error:
124+
except ORGANIZATIONS_CLIENT.exceptions.AccountNotRegisteredException:
125+
logger.debug(f"Account: {account_id} not registered for {service_principal}")
126+
except Exception as error:
122127
logger.error(f"deregister_delegated_administrator error: {error}")
123128
raise ValueError("Error trying to deregister delegated administrator account")
124129

@@ -169,7 +174,8 @@ def create(event, _):
169174
:param _:
170175
:return: DelegatedAdminResourceId
171176
"""
172-
logger.info(f"Create Event: {event}")
177+
request_type = event["RequestType"]
178+
logger.info(f"{request_type} Event")
173179
try:
174180
check_parameters(event)
175181
params = event.get("ResourceProperties")
@@ -188,6 +194,42 @@ def create(event, _):
188194
return "DelegatedAdminResourceId"
189195

190196

197+
@helper.update
198+
def update(event, _):
199+
"""
200+
CloudFormation Update Event
201+
:param event:
202+
:param _:
203+
:return:
204+
"""
205+
logger.info(f"Update Event: {event}")
206+
try:
207+
check_parameters(event)
208+
params = event.get("ResourceProperties")
209+
aws_service_principal_list = [value.strip() for value in params.get("AWS_SERVICE_PRINCIPAL_LIST", "")
210+
if value != '']
211+
check_service_principals(aws_service_principal_list)
212+
213+
old_params = event.get("OldResourceProperties")
214+
old_aws_service_principal_list = [value.strip() for value in old_params.get("AWS_SERVICE_PRINCIPAL_LIST", "")
215+
if value != '']
216+
add_list = list(set(aws_service_principal_list) - set(old_aws_service_principal_list))
217+
remove_list = list(set(old_aws_service_principal_list) - set(aws_service_principal_list))
218+
219+
if add_list:
220+
for aws_service_principal in add_list:
221+
enable_aws_service_access(aws_service_principal)
222+
register_delegated_administrator(params.get("DELEGATED_ADMIN_ACCOUNT_ID", ""), aws_service_principal)
223+
224+
if remove_list:
225+
for aws_service_principal in remove_list:
226+
deregister_delegated_administrator(params.get("DELEGATED_ADMIN_ACCOUNT_ID", ""), aws_service_principal)
227+
disable_aws_service_access(aws_service_principal)
228+
except Exception as error:
229+
logger.error(f"Exception: {error}")
230+
raise ValueError("Error updating delegated administrators")
231+
232+
191233
@helper.delete
192234
def delete(event, _):
193235
"""
@@ -201,7 +243,7 @@ def delete(event, _):
201243
check_parameters(event)
202244
params = event.get("ResourceProperties")
203245

204-
aws_service_principal_list = [value.strip() for value in params.get("AWS_SERVICE_PRINCIPAL_LIST", "").split(",")
246+
aws_service_principal_list = [value.strip() for value in params.get("AWS_SERVICE_PRINCIPAL_LIST", "")
205247
if value != '']
206248
check_service_principals(aws_service_principal_list)
207249

@@ -210,7 +252,7 @@ def delete(event, _):
210252
disable_aws_service_access(aws_service_principal)
211253
except Exception as error:
212254
logger.error(f"Exception: {error}")
213-
raise ValueError("Error disabling the admin account")
255+
raise ValueError("Error disabling delegated administrators")
214256

215257

216258
def lambda_handler(event, context):

solutions/config/aggregator-org/aws-control-tower/README.md

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,52 @@ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-
55
# Implementation Instructions
66

77
1. Make sure the required [prerequisites](../../../../extras/aws-control-tower/prerequisites/README.md) are completed
8-
2. Copy the files to the Customizations for AWS Control Tower configuration
8+
2. Package and upload the common-register-delegated-administrator Lambda function from the
9+
[Common Register Delegated Administrator Solution](../../../common/register-delegated-administrator)
10+
```shell
11+
export AWS_ACCESS_KEY_ID=INSERT_AWS_ACCESS_KEY_ID
12+
export AWS_SECRET_ACCESS_KEY=INSERT_AWS_SECRET_ACCESS_KEY
13+
export AWS_SESSION_TOKEN=INSERT_AWS_SESSION_TOKEN
14+
15+
export BUCKET=lambda-zips-CHANGE_ME_ACCOUNT_ID-CHANGE_ME_REGION
16+
sh ~/aws-security-reference-architecture-examples/extras/packaging-scripts/package-lambda.sh \
17+
--file_name common-register-delegated-admin.zip \
18+
--bucket $BUCKET \
19+
--src_dir ~/aws-security-reference-architecture-examples/solutions/common/register-delegated-admninistrator/code/src
20+
```
21+
3. Copy the files to the Customizations for AWS Control Tower configuration
922
1. customizations-for-control-tower-configuration
10-
1. [manifest.yaml](manifest.yaml)
11-
2. [common/register-delegated-administrator/aws-control-tower/parameters/common-register-delegated-administrator.json](../../../common/register-delegated-administrator/aws-control-tower/parameters/common-register-delegated-administrator.json)
12-
3. [parameters/aggregator-org-configuration.json](parameters/aggregator-org-configuration.json)
13-
4. [common/register-delegated-administrator/templates/common-register-delegated-administrator.yaml](../../../common/register-delegated-administrator/templates/common-register-delegated-administrator.yaml)
14-
5. [templates/aggregator-org-configuration.yaml](../templates/aggregator-org-configuration.yaml)
23+
1. [manifest.yaml](manifest.yaml) -> manifest.yaml
24+
2. [common/register-delegated-administrator/aws-control-tower/parameters/common-register-delegated-administrator.json](../../../common/register-delegated-administrator/aws-control-tower/parameters/common-register-delegated-administrator.json)
25+
-> parameters/common-register-delegated-administrator.json
26+
3. [parameters/aggregator-org-configuration.json](parameters/aggregator-org-configuration.json)
27+
-> parameters/aggregator-org-configuration.json
28+
4. [common/register-delegated-administrator/templates/common-register-delegated-administrator.yaml](../../../common/register-delegated-administrator/templates/common-register-delegated-administrator.yaml)
29+
-> templates/common-register-delegated-administrator.yaml
30+
5. [templates/aggregator-org-configuration.yaml](../templates/aggregator-org-configuration.yaml)
31+
-> templates/aggregator-org-configuration.yaml
1532

16-
3. Update the parameter files with any specific values for your environment
17-
4. Use the "config.amazonaws.com" value for the pServicePrincipalList
18-
5. Add the [common/register-delegated-administrator/aws-control-tower/manifest.yaml](../../../common/register-delegated-administrator/aws-control-tower)
33+
4. Update the parameter files with any specific values for your environment
34+
5. Add "access-analyzer.amazonaws.com" to the pServicePrincipalList parameter in the parameters/common-register-delegated-administrator.json
35+
6. Add the [common/register-delegated-administrator/aws-control-tower/manifest.yaml](../../../common/register-delegated-administrator/aws-control-tower)
1936
resource configuration to your manifest.yaml file.
20-
6. Update the manifest.yaml file with your account names and SSM parameters
21-
7. Deploy the Customizations for AWS Control Tower configuration
22-
8. How to verify after the pipeline completes?
37+
```yaml
38+
...
39+
cloudformation_resources:
40+
# -----------------------------------------------------------------------------
41+
# Common Register Delegated Administrator
42+
# -----------------------------------------------------------------------------
43+
- name: CommonRegisterDelegatedAdmin
44+
template_file: templates/common-register-delegated-administrator.yaml
45+
parameter_file: parameters/common-register-delegated-administrator.json
46+
deploy_method: stack_set
47+
deploy_to_account:
48+
- REPLACE_ME_ORG_MANAGEMENT_ACCOUNT_NAME
49+
...
50+
```
51+
7. Update the manifest.yaml file with your account names and SSM parameters
52+
8. Deploy the Customizations for AWS Control Tower configuration
53+
9. How to verify after the pipeline completes?
2354
1. Log into the Audit account and navigate to the AWS Config page
2455
1. Verify the correct AWS Config Aggregator configurations have been applied
2556
2. Verify all existing accounts have been enabled (This can take a few minutes to complete)

0 commit comments

Comments
 (0)