Skip to content

Commit

Permalink
Merge pull request #2 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 Jul 3, 2024
2 parents 1c7c304 + 0cbccd8 commit 88fa0b3
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 143 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
# wmaug-management-infrastructure

TypeScript multi-stack AWS CDK app for managing the AWS Management account for the West Michigan AWS Users Group.

TypeScript multi-stack AWS CDK app for managing the AWS Management account for the West Michigan AWS Users Group.

## 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.
- 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

## 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

npx cdk deploy Scp
18 changes: 9 additions & 9 deletions bin/wmaug-management-infrastructure.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { Sso } from '../lib/wmaug-management-infrastructure-sso';
import { Scp } from '../lib/wmaug-management-infrastructure-scp';
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { Sso } from "../lib/wmaug-management-infrastructure-sso";
import { Scp } from "../lib/wmaug-management-infrastructure-scp";

const app = new cdk.App();
new Sso(app, 'Sso', {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: 'us-east-2' },
new Sso(app, "Sso", {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: "us-east-2" },
});

new Scp(app, 'Scp', {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: 'us-east-2' },
});
new Scp(app, "Scp", {
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: "us-east-2" },
});
9 changes: 2 additions & 7 deletions cdk.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"app": "npx ts-node --prefer-ts-exts bin/wmaug-management-infrastructure.ts",
"watch": {
"include": [
"**"
],
"include": ["**"],
"exclude": [
"README.md",
"cdk*.json",
Expand All @@ -19,10 +17,7 @@
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
],
"@aws-cdk/core:target-partitions": ["aws", "aws-cn"],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
Expand Down
10 changes: 5 additions & 5 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/test'],
testMatch: ['**/*.test.ts'],
testEnvironment: "node",
roots: ["<rootDir>/test"],
testMatch: ["**/*.test.ts"],
transform: {
'^.+\\.tsx?$': 'ts-jest'
}
"^.+\\.tsx?$": "ts-jest",
},
};
85 changes: 40 additions & 45 deletions lib/wmaug-management-infrastructure-scp.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,51 @@
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as orgs from 'aws-cdk-lib/aws-organizations';

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": "*"
}
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"
]
}
}
}
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"],
},
},
},
},
});

}
}
}
122 changes: 73 additions & 49 deletions lib/wmaug-management-infrastructure-sso.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,110 @@
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sso from 'aws-cdk-lib/aws-sso';
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',
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 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',
});
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 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',
});
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 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'],
});
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"],
sessionDuration: "PT12H",
},
);

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

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

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


}
}
Loading

0 comments on commit 88fa0b3

Please sign in to comment.