Skip to content

Commit 6cec470

Browse files
authored
v3.1.0 (#55)
* v3.1.0 * Updated Readme to link AWS SSO region switch
1 parent 49cf0f4 commit 6cec470

34 files changed

+5074
-4003
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- [Using API interface for your use cases](#using-api-interface-for-your-use-cases)
1919
- [Using S3 interface for your use cases](#using-s3-interface-for-your-use-cases)
2020
- [Unicorn Rides use cases](https://catalog.us-east-1.prod.workshops.aws/v2/workshops/640b0bab-1f5e-494a-973e-4ed7919d397b/en-US/03-usecases)
21+
- [AWS SSO Region Switch](docs/documentation//Region-Switch.md)
2122
- [Security](#security)
2223
- [License](#license)
2324

bin/aws-sso-extensions-for-enterprise.ts

Lines changed: 90 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { BuildConfig } from "../lib/build/buildConfig";
77
import { AwsSsoExtensionsForEnterprise } from "../lib/stacks/pipeline/aws-sso-extensions-for-enterprise";
88

99
import yaml = require("js-yaml");
10+
import { RegionSwitchBuildConfig } from "../lib/build/regionSwitchBuildConfig";
11+
import { AwsSsoExtensionsRegionSwitchDiscover } from "../lib/stacks/region-switch/aws-sso-extensions-region-switch-discover";
12+
import { AwsSsoExtensionsRegionSwitchDeploy } from "../lib/stacks/region-switch/aws-sso-extensions-region-switch-deploy";
1013
const app = new App();
1114

1215
function ensureString(
@@ -159,31 +162,96 @@ function getConfig() {
159162
return buildConfig;
160163
}
161164

165+
function getRegionSwitchConfig() {
166+
/* eslint-disable @typescript-eslint/no-explicit-any */
167+
const unparsedEnv: any = yaml.load(
168+
readFileSync(resolve("./config/" + "region-switch" + ".yaml"), "utf8")
169+
);
170+
171+
const buildConfig: RegionSwitchBuildConfig = {
172+
SSOServiceAccountId: ensureString(unparsedEnv, "SSOServiceAccountId"),
173+
BootstrapQualifier: ensureString(unparsedEnv, "BootstrapQualifier"),
174+
SSOServiceAccountRegion: ensureString(
175+
unparsedEnv,
176+
"SSOServiceAccountRegion"
177+
),
178+
SSOServiceTargetAccountRegion: ensureString(
179+
unparsedEnv,
180+
"SSOServiceTargetAccountRegion"
181+
),
182+
};
183+
184+
return buildConfig;
185+
}
186+
162187
async function DeploySSOForEnterprise() {
163-
const buildConfig: BuildConfig = getConfig();
164-
165-
const AwsSsoExtensionsForEnterpriseAppName =
166-
buildConfig.Environment + "-" + buildConfig.App;
167-
const AwsSsoExtensionsForEnterpriseStack = new AwsSsoExtensionsForEnterprise(
168-
app,
169-
AwsSsoExtensionsForEnterpriseAppName,
170-
{
171-
env: {
172-
region: buildConfig.PipelineSettings.DeploymentAccountRegion,
173-
account: buildConfig.PipelineSettings.DeploymentAccountId,
188+
const env: string = app.node.tryGetContext("config");
189+
if (!env)
190+
throw new Error(
191+
"Context variable missing on CDK command. Pass in as `-c config=XXX`"
192+
);
193+
194+
if (env.toUpperCase() === "REGION-SWITCH-DISCOVER") {
195+
const buildConfig: RegionSwitchBuildConfig = getRegionSwitchConfig();
196+
const AwsSsoExtensionsRegionSwitchDiscoverAppName = `aws-sso-extensions-region-switch-discover`;
197+
new AwsSsoExtensionsRegionSwitchDiscover(
198+
app,
199+
AwsSsoExtensionsRegionSwitchDiscoverAppName,
200+
{
201+
env: {
202+
region: buildConfig.SSOServiceAccountRegion,
203+
account: buildConfig.SSOServiceAccountId,
204+
},
205+
synthesizer: new DefaultStackSynthesizer({
206+
qualifier: buildConfig.BootstrapQualifier,
207+
}),
174208
},
175-
synthesizer: new DefaultStackSynthesizer({
176-
qualifier: buildConfig.PipelineSettings.BootstrapQualifier,
177-
}),
178-
},
179-
buildConfig
180-
);
209+
buildConfig
210+
);
211+
} else if (env.toUpperCase() === "REGION-SWITCH-DEPLOY") {
212+
const buildConfig: RegionSwitchBuildConfig = getRegionSwitchConfig();
213+
const AwsSsoExtensionsRegionSwitchDeployAppName = `aws-sso-extensions-region-switch-deploy`;
214+
new AwsSsoExtensionsRegionSwitchDeploy(
215+
app,
216+
AwsSsoExtensionsRegionSwitchDeployAppName,
217+
{
218+
env: {
219+
region: buildConfig.SSOServiceTargetAccountRegion,
220+
account: buildConfig.SSOServiceAccountId,
221+
},
222+
synthesizer: new DefaultStackSynthesizer({
223+
qualifier: buildConfig.BootstrapQualifier,
224+
}),
225+
},
226+
buildConfig
227+
);
228+
} else {
229+
const buildConfig: BuildConfig = getConfig();
181230

182-
Tags.of(AwsSsoExtensionsForEnterpriseStack).add("App", buildConfig.App);
183-
Tags.of(AwsSsoExtensionsForEnterpriseStack).add(
184-
"Environment",
185-
buildConfig.Environment
186-
);
231+
const AwsSsoExtensionsForEnterpriseAppName =
232+
buildConfig.Environment + "-" + buildConfig.App;
233+
const AwsSsoExtensionsForEnterpriseStack =
234+
new AwsSsoExtensionsForEnterprise(
235+
app,
236+
AwsSsoExtensionsForEnterpriseAppName,
237+
{
238+
env: {
239+
region: buildConfig.PipelineSettings.DeploymentAccountRegion,
240+
account: buildConfig.PipelineSettings.DeploymentAccountId,
241+
},
242+
synthesizer: new DefaultStackSynthesizer({
243+
qualifier: buildConfig.PipelineSettings.BootstrapQualifier,
244+
}),
245+
},
246+
buildConfig
247+
);
248+
249+
Tags.of(AwsSsoExtensionsForEnterpriseStack).add("App", buildConfig.App);
250+
Tags.of(AwsSsoExtensionsForEnterpriseStack).add(
251+
"Environment",
252+
buildConfig.Environment
253+
);
254+
}
187255
}
188256

189257
DeploySSOForEnterprise();

config/env.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
App: "aws-sso-extensions-for-enterprise"
33
Environment: "env"
4-
Version: "3.0.3"
4+
Version: "3.1.0"
55

66
PipelineSettings:
77
BootstrapQualifier: "<your-bootstrap-qualifier>" # For example: 'ssoutility'

config/region-switch.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
BootstrapQualifier: "ssoutility"
3+
SSOServiceAccountId: "<your-sso-account-id>"
4+
SSOServiceAccountRegion: "<your-sso-service-region>"
5+
SSOServiceTargetAccountRegion: "<your-new-sso-service-region>"
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# AWS SSO Region Switch
2+
3+
AWS SSO service is single-region at this point of time. In some instances, customers wish to move their AWS SSO configuration from one region to another region and this document explains how some of these migration activities could be automated.
4+
5+
## Caveats
6+
7+
- AWS SSO at this point of time does not have API's to manage identities , instance enablement. These are manual operations.
8+
- When a customer migrates AWS SSO from one region to another region, the solution only helps automate migration of permission sets and account assignments.
9+
- The solution assumes that identities (users/groups) are onboarded into the new region using the same naming convention. For ex, if a customer had onboarded a user with user name `alpha-user`, group with display name `beta-group` in region 1 through any of the supported identity sources, the solution assumes that the customer will onboard the user with the same user name `alpha-user` and same group display name `beta-group` in region 2. Only when this condition is met, the solution automatically migrates account assignments from region 1 to region 2.
10+
11+
## Seqence
12+
13+
- `Discover` component of the solution is deployed in your current AWS SSO account and current AWS SSO region first. This would read all the permission sets, account assignments in your current AWS SSO region and persist them for later usage
14+
- The customer then manually moves the AWS SSO configuration from their current region to the new region
15+
- The customer onboards all the required identities in the new region
16+
- `Deploy` component of the solution is deployed in your current AWS SSO Account and new AWS SSO region. This would then deploy all the permission sets and account assignments similar to how they were provisioned in the old AWS SSO region.
17+
- `Destroy` components of the solution are then run to remove the artefacts created in the `Discover` and `Deploy` phase.
18+
19+
## Execute
20+
21+
- Ensure the following [pre-requisites](https://catalog.us-east-1.prod.workshops.aws/workshops/640b0bab-1f5e-494a-973e-4ed7919d397b/en-US/00-prerequisites) are ready and available
22+
- Clone the solution code
23+
24+
```bash
25+
git clone https://github.com/aws-samples/aws-sso-extensions-for-enterprise.git solution-code
26+
```
27+
28+
- From the root of the project run `yarn install --frozen-lock-file`
29+
- Navigate to `lib\lambda-layers\nodejs-layer\nodejs` and run `yarn install --frozen-lock-file`
30+
- Set the environment variables in your shell
31+
32+
```bash
33+
export BOOTSTRAP_QUALIFIER="ssoutility"
34+
export CFN_EXECUTION_POLICIES="arn:aws:iam::aws:policy/AdministratorAccess"
35+
export CONFIG="region-switch-discover"
36+
export SSO_PROFILE=<your-org-main-account-profile-name>
37+
export SSO_ACCOUNT=<your-org-main-account-id>
38+
export SSO_REGION=<your-sso-service-region>
39+
```
40+
41+
- Using your org main (i.e. SSO service account) and current AWS SSO region credentials, run the following steps
42+
43+
```bash
44+
yarn cdk bootstrap --qualifier $BOOTSTRAP_QUALIFIER \
45+
--cloudformation-execution-policies $CFN_EXECUTION_POLICIES \
46+
aws://$SSO_ACCOUNT/$SSO_REGION \
47+
-c config=$CONFIG \
48+
--profile $SSO_PROFILE \
49+
--region $SSO_REGION
50+
```
51+
52+
- Update your environment variables to match the new AWS SSO region
53+
54+
```bash
55+
export CONFIG="region-switch-deploy"
56+
export SSO_REGION=<your-new-sso-service-region>
57+
```
58+
59+
- Using your org main (i.e. SSO service account) and new AWS SSO region credentials, run the following steps
60+
61+
```bash
62+
yarn cdk bootstrap --qualifier $BOOTSTRAP_QUALIFIER \
63+
--cloudformation-execution-policies $CFN_EXECUTION_POLICIES \
64+
aws://$SSO_ACCOUNT/$SSO_REGION \
65+
-c config=$CONFIG \
66+
--profile $SSO_PROFILE \
67+
--region $SSO_REGION
68+
```
69+
70+
- Update `config\region-switch.yaml` file with your environment values
71+
72+
```yaml
73+
BootstrapQualifier: "ssoutility"
74+
SSOServiceAccountId: "<your-Org-main-account-id>"
75+
SSOServiceAccountRegion: "<your-current-AWS-SSO-region"
76+
SSOServiceTargetAccountRegion: "<your-new-AWS-SSO-region>"
77+
```
78+
79+
- Run `Discover` phase through the following steps by using your Orgmain account and current AWS SSO region credentials:
80+
- Validate that the configuration and other dependencies are all set up by running `yarn synth-region-switch-discover` from the root of the project.
81+
- This should not return any errors and should synthesise successfully
82+
- Run `deploy-region-switch-discover` from the root of the project. Wait until the discover phase Cloudformation stacks are successfully deployed.
83+
- Set up AWS SSO in the new region, set up identity store and onboard all the identities in the new AWS SSO region, refer to service documentation [here](https://docs.aws.amazon.com/singlesignon/latest/userguide/getting-started.html).
84+
- Identiies must be on-boarded into the new AWS SSO region before running the next step.
85+
- Run `Deploy` phase through the following steps by using your Orgmain account and new AWS SSO region credentials:
86+
- Validate that the configuration and other dependencies are all set up by running `yarn synth-region-switch-deploy` from the root of the project.
87+
- This should not return any errors and should synthesise successfully
88+
- Run `deploy-region-switch` from the root of the project. Wait until the deploy phase Cloudformation stacks are successfully deployed.
89+
- Verify that all your account assignments and permission sets are successfully created in the new AWS SSO region
90+
- Post verification that everything is deployed correctly in the new AWS SSO region, delete the artefacts created for `Deploy` and `Discover` phases by running the following:
91+
- Using Orgmain and new AWS SSO region credentials, run `yarn destroy-region-switch-deploy` from the root of the project. This will remove all the deploy phase artefacts.
92+
- Using Orgmain and old AWS SSO region credentials, run `yarn destroy-region-switch-discover` from the root of the project. This will remove all the discover phase artefacts
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
Build parameters interface definition
3+
To enable easier sharing between constructs and stacks as well as
4+
synth and deploy validations
5+
*/
6+
7+
export interface RegionSwitchBuildConfig {
8+
readonly BootstrapQualifier: string;
9+
readonly SSOServiceAccountId: string;
10+
readonly SSOServiceAccountRegion: string;
11+
readonly SSOServiceTargetAccountRegion: string;
12+
}

lib/lambda-functions/package.json

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
{
22
"name": "aws-sso-extensions-for-enterprise-layer",
3-
"version": "3.0.3",
3+
"version": "3.1.0",
44
"description": "AWS SSO Permissions Utility Layer",
55
"scripts": {
66
"test": "echo \"Error: no test specified\" && exit 1"
77
},
88
"keywords": [],
99
"dependencies": {
10-
"@aws-sdk/client-dynamodb": "3.46.0",
11-
"@aws-sdk/client-identitystore": "3.46.0",
12-
"@aws-sdk/client-s3": "3.46.0",
13-
"@aws-sdk/client-sfn": "3.46.0",
14-
"@aws-sdk/client-sns": "3.46.0",
15-
"@aws-sdk/client-sqs": "3.46.0",
16-
"@aws-sdk/client-ssm": "3.46.0",
17-
"@aws-sdk/client-sso-admin": "3.46.0",
18-
"@aws-sdk/credential-providers": "3.46.0",
19-
"@aws-sdk/lib-dynamodb": "3.46.0",
20-
"@aws-sdk/util-waiter": "3.46.0",
21-
"ajv": "8.8.2",
10+
"@aws-sdk/client-dynamodb": "3.52.0",
11+
"@aws-sdk/client-identitystore": "3.52.0",
12+
"@aws-sdk/client-s3": "3.52.0",
13+
"@aws-sdk/client-sfn": "3.52.0",
14+
"@aws-sdk/client-sns": "3.52.0",
15+
"@aws-sdk/client-sqs": "3.52.0",
16+
"@aws-sdk/client-ssm": "3.52.0",
17+
"@aws-sdk/client-sso-admin": "3.52.0",
18+
"@aws-sdk/credential-providers": "3.52.0",
19+
"@aws-sdk/lib-dynamodb": "3.52.0",
20+
"@aws-sdk/util-dynamodb": "3.52.0",
21+
"@aws-sdk/util-waiter": "3.52.0",
22+
"ajv": "8.10.0",
2223
"json-diff": "0.7.1",
2324
"uuid": "8.3.2"
2425
},

0 commit comments

Comments
 (0)