Skip to content

Commit

Permalink
Merge pull request #1 from West-Michigan-AWS-Users-Group/add-cdk-depl…
Browse files Browse the repository at this point in the history
…oy-refactor-for-multiple-stacks

add-cdk-deploy-refactor-for-multiple-stacks
  • Loading branch information
tnielsen2 authored May 31, 2024
2 parents 05d7f60 + 52576f6 commit 1c7c304
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 50 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/cdk_deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
on:
push:
branches:
- develop
- main

jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: "20"
- name: Install Python dependencies and CDK
run: |
# install your Python dependencies here
npm install -g aws-cdk
python -m pip install --use-feature=fast-deps --upgrade pip
pip install -r cdk/requirements.txt
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@master
with:
aws-access-key-id: ${{ secrets.SA_CDK_DEPLOYUSER_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.SA_CDK_DEPLOYUSER_AWS_SECRET_ACCESS_KEY }}
aws-region: "us-west-2"
- name: Set Environment Name
run: |
if [ "$GITHUB_REF" == "refs/heads/develop" ]; then
AWS_ENV="devA"
elif [ "$GITHUB_REF" == "refs/heads/main" ]; then
AWS_ENV="productionA"
else
echo "Skipping workflow for branch $GITHUB_REF"
exit 0
fi
echo "Setting stack name to $AWS_ENV"
echo "AWS_ENV=$AWS_ENV" >> $GITHUB_ENV
- name: CDK synth
if: ${{ env.AWS_ENV == 'devA' || env.AWS_ENV == 'productionA' }}
run: npx cdk synth ${{ env.AWS_ENV }} --require-approval=never
- name: CDK diff
if: ${{ env.AWS_ENV == 'devA' || env.AWS_ENV == 'productionA' }}
run: npx cdk diff ${{ env.AWS_ENV }} --require-approval=never
- name: CDK cdk deploy
if: ${{ env.AWS_ENV == 'devA' || env.AWS_ENV == 'productionA' }}
run: npx cdk deploy ${{ env.AWS_ENV }} --require-approval=never --all
47 changes: 47 additions & 0 deletions .github/workflows/cdk_review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
on:
pull_request:
branches: [develop]
paths:
- cdk/**
types: [opened, reopened, synchronize]

workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: "20"

- name: Install Python dependencies and CDK
run: |
# install your Python dependencies here
npm install -g aws-cdk
python -m pip install --use-feature=fast-deps --upgrade pip
pip install -r cdk/requirements.txt
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@master
with:
aws-access-key-id: ${{ secrets.SA_CDK_DEPLOYUSER_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.SA_CDK_DEPLOYUSER_AWS_SECRET_ACCESS_KEY }}
aws-region: "us-east-2"

- name: CDK synth
run: npx cdk synth --require-approval=never

- name: CDK diff
run: npx cdk synth --require-approval=never
31 changes: 19 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
# Welcome to your CDK TypeScript project
# wmaug-management-infrastructure

This is a blank project for CDK development with TypeScript.
TypeScript multi-stack AWS CDK app for managing the AWS Management account for the West Michigan AWS Users Group.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands
## Stack information
- Sso
- Creates the AWS SSO resources for the WMAUG Management account.
- Creates and defines permissions for groups.
- Assigns groups to permission sets
- Scp
- Stack containing SCPs for the WMAUG org.
- Deny the creation of access keys
- Deny the deployment of resources in any region other than us-east-1 and us-east-2

* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `npx cdk deploy` deploy this stack to your default AWS account/region
* `npx cdk diff` compare deployed stack with current state
* `npx cdk synth` emits the synthesized CloudFormation template
## Manually deploying the Sso stack
npx cdk deploy Sso --parameters instanceArnParam="arn:aws:sso:::instance/ssoins-123456789abcdefg" \
--parameters wmaugManagementAccountNumberParam="123456789abcd" \
--parameters wmaugModeratorAccountNumberParam="123456789abcd" \
--parameters wmaugModeratorAdminGroupId="12345678-1234-1234-1234-abcdefghijkl" \
--parameters wmaugFullAdminGroupId="12345678-1234-1234-1234-abcdefghijkl"

## Manually deploying the Scp stack
npx cdk deploy Scp

## Deploying and using this stack
AWS_DEFAULT_PROFILE=profile-name npx cdk deploy --parameters instanceArnParam="arn:aws:sso:::instance/ssoins-123456789abc"
21 changes: 7 additions & 14 deletions bin/wmaug-management-infrastructure.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { WmaugManagementInfrastructureStack } from '../lib/wmaug-management-infrastructure-stack';
import { Sso } from '../lib/wmaug-management-infrastructure-sso';
import { Scp } from '../lib/wmaug-management-infrastructure-scp';

const app = new cdk.App();
new WmaugManagementInfrastructureStack(app, 'WmaugManagementInfrastructureStack', {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */
new Sso(app, 'Sso', {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: 'us-east-2' },
});

/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },

/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
new Scp(app, 'Scp', {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: 'us-east-2' },
});
56 changes: 56 additions & 0 deletions lib/wmaug-management-infrastructure-scp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as orgs from 'aws-cdk-lib/aws-organizations';


export class Scp extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

new orgs.CfnPolicy(this, 'denyIamAccessKeyCreation', {
name: 'denyIamAccessKeyCreation',
description: 'Deny IAM access key creation',
type: 'SERVICE_CONTROL_POLICY',
content:{
"Version": "2012-10-17",
"Statement": {
"Effect": "Deny",
"Action": [
"iam:CreateAccessKey",
"iam:CreateUser",
"iam:CreateLoginProfile",
"iam:UpdateLoginProfile",
"iam:DeleteAccessKey",
"iam:DeleteUser",
"iam:DeleteLoginProfile"
],
"Resource": "*"
}
},
});

// create SCP blocking access to all regions except us-east-1 and us-east-2
new orgs.CfnPolicy(this, 'denyAllRegionsExceptUSEast', {
name: 'denyAllRegionsExceptUSEast',
description: 'Deny all regions except us-east-1 and us-east-2',
type: 'SERVICE_CONTROL_POLICY',
content:{
"Version": "2012-10-17",
"Statement": {
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"us-east-1",
"us-east-2"
]
}
}
}
},
});

}
}
86 changes: 86 additions & 0 deletions lib/wmaug-management-infrastructure-sso.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sso from 'aws-cdk-lib/aws-sso';

export class Sso extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const instanceArnParam = new cdk.CfnParameter(this, 'instanceArnParam', {
type: 'String',
description: 'The ARN of the SSO instance',
});

// start account number parameters
const wmaugManagementAccountNumberParam = new cdk.CfnParameter(this, 'wmaugManagementAccountNumberParam', {
type: 'String',
description: 'The account number of the WMAUG management account',
});

const wmaugModeratorAccountNumberParam = new cdk.CfnParameter(this, 'wmaugModeratorAccountNumberParam', {
type: 'String',
description: 'The account number of the WMAUG moderator account',
});

// start group GUID parameters

const wmaugModeratorAdminGroupId = new cdk.CfnParameter(this, 'wmaugModeratorAdminGroupId', {
type: 'String',
description: 'The GUID of the wmaugModeratorAdmin SSO group',
});

const wmaugFullAdminGroupId = new cdk.CfnParameter(this, 'wmaugFullAdminGroupId', {
type: 'String',
description: 'The GUID of the wmaugFullAdmin SSO group',
});

// Start permission set policy creation
const wmaugModeratorAdminPermissionSet = new sso.CfnPermissionSet(this, 'wmaugModeratorAdminPermissionSet', {
// Use the value of the CFN parameter
instanceArn: instanceArnParam.valueAsString,
name: 'wmaugModeratorAdminPermissionSet',
description: 'Permission set WMAUG moderators and administrators will use',
managedPolicies: ['arn:aws:iam::aws:policy/AdministratorAccess'],
});

const wmaugFullAdminPermissionSet = new sso.CfnPermissionSet(this, 'wmaugFullAdminPermissionSet', {
// Use the value of the CFN parameter
instanceArn: instanceArnParam.valueAsString,
name: 'wmaugFullAdminPermissionSet',
description: 'Permission set WMAUG owners will use',
managedPolicies: ['arn:aws:iam::aws:policy/AdministratorAccess'],
});

// Assign moderator admin to moderator account
new sso.CfnAssignment(this, 'wmaugModeratorAdminModeratorAssignment', {
instanceArn: instanceArnParam.valueAsString,
permissionSetArn: wmaugModeratorAdminPermissionSet.attrPermissionSetArn,
principalType: 'GROUP',
principalId: wmaugModeratorAdminGroupId.valueAsString,
targetId: wmaugModeratorAccountNumberParam.valueAsString,
targetType: 'AWS_ACCOUNT',
});

// Assign full admin to management account
new sso.CfnAssignment(this, 'wmaugFullAdminManagementAssignment', {
instanceArn: instanceArnParam.valueAsString,
permissionSetArn: wmaugFullAdminPermissionSet.attrPermissionSetArn,
principalType: 'GROUP',
principalId: wmaugFullAdminGroupId.valueAsString,
targetId: wmaugManagementAccountNumberParam.valueAsString,
targetType: 'AWS_ACCOUNT',
});

// Assign full admin to moderator account
new sso.CfnAssignment(this, 'wmaugFullAdminModeratorAssignment', {
instanceArn: instanceArnParam.valueAsString,
permissionSetArn: wmaugFullAdminPermissionSet.attrPermissionSetArn,
principalType: 'GROUP',
principalId: wmaugFullAdminGroupId.valueAsString,
targetId: wmaugModeratorAccountNumberParam.valueAsString,
targetType: 'AWS_ACCOUNT',
});
}


}
23 changes: 0 additions & 23 deletions lib/wmaug-management-infrastructure-stack.ts

This file was deleted.

2 changes: 1 addition & 1 deletion test/wmaug-management-infrastructure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// import * as WmaugManagementInfrastructure from '../lib/wmaug-management-infrastructure-stack';

// example test. To run these tests, uncomment this file along with the
// example resource in lib/wmaug-management-infrastructure-stack.ts
// example resource in lib/wmaug-management-infrastructure-sso.ts
test('SQS Queue Created', () => {
// const app = new cdk.App();
// // WHEN
Expand Down

0 comments on commit 1c7c304

Please sign in to comment.