Skip to content

Commit

Permalink
v3.1.0 (#55)
Browse files Browse the repository at this point in the history
* v3.1.0

* Updated Readme to link AWS SSO region switch
  • Loading branch information
leelalagudu authored Feb 24, 2022
1 parent 49cf0f4 commit 6cec470
Show file tree
Hide file tree
Showing 34 changed files with 5,074 additions and 4,003 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [Using API interface for your use cases](#using-api-interface-for-your-use-cases)
- [Using S3 interface for your use cases](#using-s3-interface-for-your-use-cases)
- [Unicorn Rides use cases](https://catalog.us-east-1.prod.workshops.aws/v2/workshops/640b0bab-1f5e-494a-973e-4ed7919d397b/en-US/03-usecases)
- [AWS SSO Region Switch](docs/documentation//Region-Switch.md)
- [Security](#security)
- [License](#license)

Expand Down
112 changes: 90 additions & 22 deletions bin/aws-sso-extensions-for-enterprise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { BuildConfig } from "../lib/build/buildConfig";
import { AwsSsoExtensionsForEnterprise } from "../lib/stacks/pipeline/aws-sso-extensions-for-enterprise";

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

function ensureString(
Expand Down Expand Up @@ -159,31 +162,96 @@ function getConfig() {
return buildConfig;
}

function getRegionSwitchConfig() {
/* eslint-disable @typescript-eslint/no-explicit-any */
const unparsedEnv: any = yaml.load(
readFileSync(resolve("./config/" + "region-switch" + ".yaml"), "utf8")
);

const buildConfig: RegionSwitchBuildConfig = {
SSOServiceAccountId: ensureString(unparsedEnv, "SSOServiceAccountId"),
BootstrapQualifier: ensureString(unparsedEnv, "BootstrapQualifier"),
SSOServiceAccountRegion: ensureString(
unparsedEnv,
"SSOServiceAccountRegion"
),
SSOServiceTargetAccountRegion: ensureString(
unparsedEnv,
"SSOServiceTargetAccountRegion"
),
};

return buildConfig;
}

async function DeploySSOForEnterprise() {
const buildConfig: BuildConfig = getConfig();

const AwsSsoExtensionsForEnterpriseAppName =
buildConfig.Environment + "-" + buildConfig.App;
const AwsSsoExtensionsForEnterpriseStack = new AwsSsoExtensionsForEnterprise(
app,
AwsSsoExtensionsForEnterpriseAppName,
{
env: {
region: buildConfig.PipelineSettings.DeploymentAccountRegion,
account: buildConfig.PipelineSettings.DeploymentAccountId,
const env: string = app.node.tryGetContext("config");
if (!env)
throw new Error(
"Context variable missing on CDK command. Pass in as `-c config=XXX`"
);

if (env.toUpperCase() === "REGION-SWITCH-DISCOVER") {
const buildConfig: RegionSwitchBuildConfig = getRegionSwitchConfig();
const AwsSsoExtensionsRegionSwitchDiscoverAppName = `aws-sso-extensions-region-switch-discover`;
new AwsSsoExtensionsRegionSwitchDiscover(
app,
AwsSsoExtensionsRegionSwitchDiscoverAppName,
{
env: {
region: buildConfig.SSOServiceAccountRegion,
account: buildConfig.SSOServiceAccountId,
},
synthesizer: new DefaultStackSynthesizer({
qualifier: buildConfig.BootstrapQualifier,
}),
},
synthesizer: new DefaultStackSynthesizer({
qualifier: buildConfig.PipelineSettings.BootstrapQualifier,
}),
},
buildConfig
);
buildConfig
);
} else if (env.toUpperCase() === "REGION-SWITCH-DEPLOY") {
const buildConfig: RegionSwitchBuildConfig = getRegionSwitchConfig();
const AwsSsoExtensionsRegionSwitchDeployAppName = `aws-sso-extensions-region-switch-deploy`;
new AwsSsoExtensionsRegionSwitchDeploy(
app,
AwsSsoExtensionsRegionSwitchDeployAppName,
{
env: {
region: buildConfig.SSOServiceTargetAccountRegion,
account: buildConfig.SSOServiceAccountId,
},
synthesizer: new DefaultStackSynthesizer({
qualifier: buildConfig.BootstrapQualifier,
}),
},
buildConfig
);
} else {
const buildConfig: BuildConfig = getConfig();

Tags.of(AwsSsoExtensionsForEnterpriseStack).add("App", buildConfig.App);
Tags.of(AwsSsoExtensionsForEnterpriseStack).add(
"Environment",
buildConfig.Environment
);
const AwsSsoExtensionsForEnterpriseAppName =
buildConfig.Environment + "-" + buildConfig.App;
const AwsSsoExtensionsForEnterpriseStack =
new AwsSsoExtensionsForEnterprise(
app,
AwsSsoExtensionsForEnterpriseAppName,
{
env: {
region: buildConfig.PipelineSettings.DeploymentAccountRegion,
account: buildConfig.PipelineSettings.DeploymentAccountId,
},
synthesizer: new DefaultStackSynthesizer({
qualifier: buildConfig.PipelineSettings.BootstrapQualifier,
}),
},
buildConfig
);

Tags.of(AwsSsoExtensionsForEnterpriseStack).add("App", buildConfig.App);
Tags.of(AwsSsoExtensionsForEnterpriseStack).add(
"Environment",
buildConfig.Environment
);
}
}

DeploySSOForEnterprise();
2 changes: 1 addition & 1 deletion config/env.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
App: "aws-sso-extensions-for-enterprise"
Environment: "env"
Version: "3.0.3"
Version: "3.1.0"

PipelineSettings:
BootstrapQualifier: "<your-bootstrap-qualifier>" # For example: 'ssoutility'
Expand Down
5 changes: 5 additions & 0 deletions config/region-switch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
BootstrapQualifier: "ssoutility"
SSOServiceAccountId: "<your-sso-account-id>"
SSOServiceAccountRegion: "<your-sso-service-region>"
SSOServiceTargetAccountRegion: "<your-new-sso-service-region>"
92 changes: 92 additions & 0 deletions docs/documentation/Region-Switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# AWS SSO Region Switch

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.

## Caveats

- AWS SSO at this point of time does not have API's to manage identities , instance enablement. These are manual operations.
- When a customer migrates AWS SSO from one region to another region, the solution only helps automate migration of permission sets and account assignments.
- 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.

## Seqence

- `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
- The customer then manually moves the AWS SSO configuration from their current region to the new region
- The customer onboards all the required identities in the new region
- `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.
- `Destroy` components of the solution are then run to remove the artefacts created in the `Discover` and `Deploy` phase.

## Execute

- 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
- Clone the solution code

```bash
git clone https://github.com/aws-samples/aws-sso-extensions-for-enterprise.git solution-code
```

- From the root of the project run `yarn install --frozen-lock-file`
- Navigate to `lib\lambda-layers\nodejs-layer\nodejs` and run `yarn install --frozen-lock-file`
- Set the environment variables in your shell

```bash
export BOOTSTRAP_QUALIFIER="ssoutility"
export CFN_EXECUTION_POLICIES="arn:aws:iam::aws:policy/AdministratorAccess"
export CONFIG="region-switch-discover"
export SSO_PROFILE=<your-org-main-account-profile-name>
export SSO_ACCOUNT=<your-org-main-account-id>
export SSO_REGION=<your-sso-service-region>
```

- Using your org main (i.e. SSO service account) and current AWS SSO region credentials, run the following steps

```bash
yarn cdk bootstrap --qualifier $BOOTSTRAP_QUALIFIER \
--cloudformation-execution-policies $CFN_EXECUTION_POLICIES \
aws://$SSO_ACCOUNT/$SSO_REGION \
-c config=$CONFIG \
--profile $SSO_PROFILE \
--region $SSO_REGION
```

- Update your environment variables to match the new AWS SSO region

```bash
export CONFIG="region-switch-deploy"
export SSO_REGION=<your-new-sso-service-region>
```

- Using your org main (i.e. SSO service account) and new AWS SSO region credentials, run the following steps

```bash
yarn cdk bootstrap --qualifier $BOOTSTRAP_QUALIFIER \
--cloudformation-execution-policies $CFN_EXECUTION_POLICIES \
aws://$SSO_ACCOUNT/$SSO_REGION \
-c config=$CONFIG \
--profile $SSO_PROFILE \
--region $SSO_REGION
```

- Update `config\region-switch.yaml` file with your environment values

```yaml
BootstrapQualifier: "ssoutility"
SSOServiceAccountId: "<your-Org-main-account-id>"
SSOServiceAccountRegion: "<your-current-AWS-SSO-region"
SSOServiceTargetAccountRegion: "<your-new-AWS-SSO-region>"
```
- Run `Discover` phase through the following steps by using your Orgmain account and current AWS SSO region credentials:
- Validate that the configuration and other dependencies are all set up by running `yarn synth-region-switch-discover` from the root of the project.
- This should not return any errors and should synthesise successfully
- Run `deploy-region-switch-discover` from the root of the project. Wait until the discover phase Cloudformation stacks are successfully deployed.
- 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).
- Identiies must be on-boarded into the new AWS SSO region before running the next step.
- Run `Deploy` phase through the following steps by using your Orgmain account and new AWS SSO region credentials:
- Validate that the configuration and other dependencies are all set up by running `yarn synth-region-switch-deploy` from the root of the project.
- This should not return any errors and should synthesise successfully
- Run `deploy-region-switch` from the root of the project. Wait until the deploy phase Cloudformation stacks are successfully deployed.
- Verify that all your account assignments and permission sets are successfully created in the new AWS SSO region
- 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:
- 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.
- 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
12 changes: 12 additions & 0 deletions lib/build/regionSwitchBuildConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Build parameters interface definition
To enable easier sharing between constructs and stacks as well as
synth and deploy validations
*/

export interface RegionSwitchBuildConfig {
readonly BootstrapQualifier: string;
readonly SSOServiceAccountId: string;
readonly SSOServiceAccountRegion: string;
readonly SSOServiceTargetAccountRegion: string;
}
27 changes: 14 additions & 13 deletions lib/lambda-functions/package.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
{
"name": "aws-sso-extensions-for-enterprise-layer",
"version": "3.0.3",
"version": "3.1.0",
"description": "AWS SSO Permissions Utility Layer",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"dependencies": {
"@aws-sdk/client-dynamodb": "3.46.0",
"@aws-sdk/client-identitystore": "3.46.0",
"@aws-sdk/client-s3": "3.46.0",
"@aws-sdk/client-sfn": "3.46.0",
"@aws-sdk/client-sns": "3.46.0",
"@aws-sdk/client-sqs": "3.46.0",
"@aws-sdk/client-ssm": "3.46.0",
"@aws-sdk/client-sso-admin": "3.46.0",
"@aws-sdk/credential-providers": "3.46.0",
"@aws-sdk/lib-dynamodb": "3.46.0",
"@aws-sdk/util-waiter": "3.46.0",
"ajv": "8.8.2",
"@aws-sdk/client-dynamodb": "3.52.0",
"@aws-sdk/client-identitystore": "3.52.0",
"@aws-sdk/client-s3": "3.52.0",
"@aws-sdk/client-sfn": "3.52.0",
"@aws-sdk/client-sns": "3.52.0",
"@aws-sdk/client-sqs": "3.52.0",
"@aws-sdk/client-ssm": "3.52.0",
"@aws-sdk/client-sso-admin": "3.52.0",
"@aws-sdk/credential-providers": "3.52.0",
"@aws-sdk/lib-dynamodb": "3.52.0",
"@aws-sdk/util-dynamodb": "3.52.0",
"@aws-sdk/util-waiter": "3.52.0",
"ajv": "8.10.0",
"json-diff": "0.7.1",
"uuid": "8.3.2"
},
Expand Down
Loading

0 comments on commit 6cec470

Please sign in to comment.