diff --git a/bin/p6lzctl b/bin/p6lzctl index 532655d..7b00d5c 100755 --- a/bin/p6lzctl +++ b/bin/p6lzctl @@ -719,6 +719,14 @@ p6_lz_run_phase_4_sandbox_account() { local action="$1" p6_h2 "Phase 4: Sandbox" + + p6_h3 "Phase 4: Sandbox: My IP" + local my_ip=$(p6_network_ip_public) + local cidr_ip="$my_ip/32" + jq --arg ip "$cidr_ip" '.["my-ip"] = $ip' cdk.context.json >tmp.$$.json + p6_file_move tmp.$$.json cdk.context.json + + p6_h3 "Phase 4: Sandbox: CDK" p6_awscdk_cli_execute $action p6-lz-sandbox p6_return_void diff --git a/node-v22.11.0-linux-x64.tar.xz b/node-v22.11.0-linux-x64.tar.xz deleted file mode 100644 index cdc6a6f..0000000 Binary files a/node-v22.11.0-linux-x64.tar.xz and /dev/null differ diff --git a/src/constructs/p6-lz-sra-central-bucket.ts b/src/constructs/p6-lz-sra-central-bucket.ts index 3fedd82..9db5502 100644 --- a/src/constructs/p6-lz-sra-central-bucket.ts +++ b/src/constructs/p6-lz-sra-central-bucket.ts @@ -1,6 +1,6 @@ import type { IPrincipal } from 'aws-cdk-lib/aws-iam' import type { Construct } from 'constructs' -import type { ShareWithOrg } from '../types' +import type { IShareWithOrg } from '../types' import * as cdk from 'aws-cdk-lib' import * as iam from 'aws-cdk-lib/aws-iam' import * as kms from 'aws-cdk-lib/aws-kms' @@ -29,7 +29,7 @@ import * as s3 from 'aws-cdk-lib/aws-s3' * */ -export interface IP6LzSraCentralBucketProps extends ShareWithOrg {} +export interface IP6LzSraCentralBucketProps extends IShareWithOrg {} export class P6LzSraCentralBucket extends cdk.Resource { constructor(scope: Construct, id: string, props: IP6LzSraCentralBucketProps) { diff --git a/src/constructs/p6-lz-sra-cloudwatch.ts b/src/constructs/p6-lz-sra-cloudwatch.ts index efe532c..d7e9a58 100644 --- a/src/constructs/p6-lz-sra-cloudwatch.ts +++ b/src/constructs/p6-lz-sra-cloudwatch.ts @@ -1,11 +1,11 @@ import type { Construct } from 'constructs' -import type { AccountAlias } from '../types' +import type { IAccountAlias } from '../types' import * as cdk from 'aws-cdk-lib' import * as iam from 'aws-cdk-lib/aws-iam' import * as kms from 'aws-cdk-lib/aws-kms' import * as logs from 'aws-cdk-lib/aws-logs' -export interface IP6LzSraCloudWatchProps extends AccountAlias {} +export interface IP6LzSraCloudWatchProps extends IAccountAlias {} export class P6LzSraCloudWatch extends cdk.Resource { public readonly logGroup: logs.ILogGroup diff --git a/src/constructs/p6-lz-sra-config.ts b/src/constructs/p6-lz-sra-config.ts index 49b9fae..9dc7b4a 100644 --- a/src/constructs/p6-lz-sra-config.ts +++ b/src/constructs/p6-lz-sra-config.ts @@ -1,11 +1,11 @@ import type { Construct } from 'constructs' -import type { LogarchiveBucket, ShareWithOrg } from '../types' +import type { ILogarchiveBucket, IShareWithOrg } from '../types' import * as cdk from 'aws-cdk-lib' import * as config from 'aws-cdk-lib/aws-config' import * as iam from 'aws-cdk-lib/aws-iam' import * as kms from 'aws-cdk-lib/aws-kms' -export interface IP6LzSraConfigProps extends ShareWithOrg, LogarchiveBucket { +export interface IP6LzSraConfigProps extends IShareWithOrg, ILogarchiveBucket { // @default false isCentral?: boolean } diff --git a/src/constructs/p6-lz-sra-org-trail.ts b/src/constructs/p6-lz-sra-org-trail.ts index 84e6169..6be8914 100644 --- a/src/constructs/p6-lz-sra-org-trail.ts +++ b/src/constructs/p6-lz-sra-org-trail.ts @@ -1,12 +1,12 @@ import type * as logs from 'aws-cdk-lib/aws-logs' import type { Construct } from 'constructs' -import type { LogarchiveBucket } from '../types' +import type { ILogarchiveBucket } from '../types' import * as cdk from 'aws-cdk-lib' import * as cloudtrail from 'aws-cdk-lib/aws-cloudtrail' import * as iam from 'aws-cdk-lib/aws-iam' import * as kms from 'aws-cdk-lib/aws-kms' -export interface IP6LzSraOrgTrailProps extends LogarchiveBucket { +export interface IP6LzSraOrgTrailProps extends ILogarchiveBucket { logGroup: logs.ILogGroup logRole: iam.IRole } diff --git a/src/constructs/p6-lz-vpc.ts b/src/constructs/p6-lz-vpc.ts new file mode 100644 index 0000000..7a3a2bd --- /dev/null +++ b/src/constructs/p6-lz-vpc.ts @@ -0,0 +1,54 @@ +import type { Construct } from 'constructs' +import type { IVpc } from '../types' +import * as cdk from 'aws-cdk-lib' +import * as ec2 from 'aws-cdk-lib/aws-ec2' + +export interface IP6LzVpcProps extends cdk.StackProps, IVpc {} + +export class P6LzVpc extends cdk.Resource { + constructor(scope: Construct, id: string, props: IP6LzVpcProps) { + super(scope, id) + + const vpc = new ec2.Vpc(this, 'VPC', { + ipAddresses: props.cidr, + maxAzs: 4, + subnetConfiguration: [ + { + cidrMask: 20, + name: 'Bastion', + subnetType: ec2.SubnetType.PUBLIC, + }, + { + cidrMask: 20, + name: 'Public', + subnetType: ec2.SubnetType.PUBLIC, + }, + { + cidrMask: 20, + name: 'Private', + subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, + }, + { + cidrMask: 20, + name: 'Isolated', + subnetType: ec2.SubnetType.PRIVATE_ISOLATED, + }, + ], + }) + + const bastion = new ec2.BastionHostLinux(this, 'p6-lz-bastion', { + instanceName: 'p6-lz-bastion', + vpc, + subnetSelection: { subnetType: ec2.SubnetType.PUBLIC }, + instanceType: new ec2.InstanceType('t4g.nano'), + }) + bastion.allowSshAccessFrom(props.myIp) + + const sg = new ec2.SecurityGroup(this, 'p6-lz-sg-default', { + vpc, + allowAllOutbound: true, + }) + sg.addIngressRule(bastion.connections.securityGroups[0]!, ec2.Port.SSH, 'Allow SSH from Bastion Host') + cdk.Tags.of(sg).add('Name', 'p6-lz-sg-default') + } +} diff --git a/src/deploy.ts b/src/deploy.ts index f7a1817..9cee1a1 100644 --- a/src/deploy.ts +++ b/src/deploy.ts @@ -2,6 +2,7 @@ import process from 'node:process' import * as cdk from 'aws-cdk-lib' +import * as ec2 from 'aws-cdk-lib/aws-ec2' import { AuditAccountStack1 } from './stacks/audit-1' import { AuditAccountStack2 } from './stacks/audit-2' import { AuditAccountStack3 } from './stacks/audit-3' @@ -36,6 +37,7 @@ const prodAccountId = accounts.find(account => account.Name === 'prod')?.Account const qaAccountId = accounts.find(account => account.Name === 'qa')?.AccountId ?? '012345678912' const sharedAccountId = accounts.find(account => account.Name === 'shared')?.AccountId ?? '012345678912' const sandboxAccountId = accounts.find(account => account.Name === 'sandbox')?.AccountId ?? '012345678912' +const myIp = app.node.tryGetContext('my-ip') ?? '0.0.0.1/32' const principals: string[] = [ auditAccountId, @@ -158,6 +160,8 @@ new SandboxAccountStack(app, 'p6-lz-sandbox', { region: env.region, }, accountAlias: 'p6m7g8-sandbox', + cidr: ec2.IpAddresses.cidr('10.252.0.0/16'), + myIp: ec2.Peer.ipv4(myIp), }) // Dev Account @@ -167,6 +171,8 @@ new DevAccountStack(app, 'p6-lz-dev', { region: env.region, }, accountAlias: 'p6m7g8-dev', + cidr: ec2.IpAddresses.cidr('10.253.0.0/16'), + myIp: ec2.Peer.ipv4(myIp), }) // QA @@ -176,6 +182,8 @@ new QaAccountStack(app, 'p6-lz-qa', { region: env.region, }, accountAlias: 'p6m7g8-qa', + cidr: ec2.IpAddresses.cidr('10.254.0.0/16'), + myIp: ec2.Peer.ipv4(myIp), }) // Prod @@ -185,6 +193,8 @@ new ProdAccountStack(app, 'p6-lz-prod', { region: env.region, }, accountAlias: 'p6m7g8-prod', + cidr: ec2.IpAddresses.cidr('10.255.0.0/16'), + myIp: ec2.Peer.ipv4(myIp), }) app.synth() diff --git a/src/stacks/audit-1.ts b/src/stacks/audit-1.ts index 2bce6a7..8fc5fac 100644 --- a/src/stacks/audit-1.ts +++ b/src/stacks/audit-1.ts @@ -1,12 +1,12 @@ import type { Construct } from 'constructs' -import type { AccountAlias, LogarchiveBucketArn, ShareWithOrg } from '../types' +import type { IAccountAlias, ILogarchiveBucketArn, IShareWithOrg } from '../types' import * as cdk from 'aws-cdk-lib' import * as s3 from 'aws-cdk-lib/aws-s3' import { P6CDKNamer } from 'p6-cdk-namer' import { P6LzSraCloudWatch } from '../constructs/p6-lz-sra-cloudwatch' import { P6LzSraOrgTrail } from '../constructs/p6-lz-sra-org-trail' -interface AuditAccountStack1Props extends cdk.StackProps, AccountAlias, ShareWithOrg, LogarchiveBucketArn {} +interface AuditAccountStack1Props extends cdk.StackProps, IAccountAlias, IShareWithOrg, ILogarchiveBucketArn {} export class AuditAccountStack1 extends cdk.Stack { constructor(scope: Construct, id: string, props: AuditAccountStack1Props) { diff --git a/src/stacks/audit-2.ts b/src/stacks/audit-2.ts index 0db1dd0..61da0d3 100644 --- a/src/stacks/audit-2.ts +++ b/src/stacks/audit-2.ts @@ -1,13 +1,13 @@ import type { Construct } from 'constructs' -import type { ShareWithOrg } from '../types' -import type { LogarchiveBucketArn } from './../types' +import type { IShareWithOrg } from '../types' +import type { ILogarchiveBucketArn } from './../types' import * as cdk from 'aws-cdk-lib' import * as s3 from 'aws-cdk-lib/aws-s3' import { P6LzSraChatbot } from '../constructs/p6-lz-sra-chatbot' import { P6LzSraConfig } from '../constructs/p6-lz-sra-config' import { P6LzSraSecurityhub } from '../constructs/p6-lz-sra-security-hub' -interface AuditAccountStack2Props extends cdk.StackProps, ShareWithOrg, LogarchiveBucketArn {} +interface AuditAccountStack2Props extends cdk.StackProps, IShareWithOrg, ILogarchiveBucketArn {} export class AuditAccountStack2 extends cdk.Stack { constructor(scope: Construct, id: string, props: AuditAccountStack2Props) { diff --git a/src/stacks/dev.ts b/src/stacks/dev.ts index 18a832e..b623ee9 100644 --- a/src/stacks/dev.ts +++ b/src/stacks/dev.ts @@ -1,9 +1,10 @@ import type { Construct } from 'constructs' -import type { AccountAlias } from '../types' +import type { IAccountAlias, IVpc } from '../types' import * as cdk from 'aws-cdk-lib' import { P6CDKNamer } from 'p6-cdk-namer' +import { P6LzVpc } from '../constructs/p6-lz-vpc' -interface DevAccountStack2Props extends cdk.StackProps, AccountAlias {} +interface DevAccountStack2Props extends cdk.StackProps, IAccountAlias, IVpc {} export class DevAccountStack extends cdk.Stack { constructor(scope: Construct, id: string, props: DevAccountStack2Props) { @@ -12,5 +13,10 @@ export class DevAccountStack extends cdk.Stack { new P6CDKNamer(this, 'P6CDKNamer', { accountAlias: props.accountAlias, }) + + new P6LzVpc(this, 'P6LzVpc', { + cidr: props.cidr, + myIp: props.myIp, + }) } } diff --git a/src/stacks/logarchive-1.ts b/src/stacks/logarchive-1.ts index 0a6aca1..9f4f7d9 100644 --- a/src/stacks/logarchive-1.ts +++ b/src/stacks/logarchive-1.ts @@ -1,10 +1,10 @@ import type { Construct } from 'constructs' -import type { AccountAlias, ShareWithOrg } from '../types' +import type { IAccountAlias, IShareWithOrg } from '../types' import * as cdk from 'aws-cdk-lib' import { P6CDKNamer } from 'p6-cdk-namer' import { P6LzSraCentralBucket } from '../constructs/p6-lz-sra-central-bucket' -interface LogarchiveAccountStack1Props extends cdk.StackProps, AccountAlias, ShareWithOrg {} +interface LogarchiveAccountStack1Props extends cdk.StackProps, IAccountAlias, IShareWithOrg {} export class LogarchiveAccountStack1 extends cdk.Stack { constructor(scope: Construct, id: string, props: LogarchiveAccountStack1Props) { diff --git a/src/stacks/logarchive-2.ts b/src/stacks/logarchive-2.ts index 5b6e3dd..f2f0183 100644 --- a/src/stacks/logarchive-2.ts +++ b/src/stacks/logarchive-2.ts @@ -1,10 +1,10 @@ import type { Construct } from 'constructs' -import type { LogarchiveBucketArn, ShareWithOrg } from '../types' +import type { ILogarchiveBucketArn, IShareWithOrg } from '../types' import * as cdk from 'aws-cdk-lib' import * as s3 from 'aws-cdk-lib/aws-s3' import { P6LzSraConfig } from '../constructs/p6-lz-sra-config' -interface LogarchiveAccountStack2Props extends cdk.StackProps, LogarchiveBucketArn, ShareWithOrg {} +interface LogarchiveAccountStack2Props extends cdk.StackProps, ILogarchiveBucketArn, IShareWithOrg {} export class LogarchiveAccountStack2 extends cdk.Stack { constructor(scope: Construct, id: string, props: LogarchiveAccountStack2Props) { diff --git a/src/stacks/management-1-organization.ts b/src/stacks/management-1-organization.ts index 6c59c87..764fd9e 100644 --- a/src/stacks/management-1-organization.ts +++ b/src/stacks/management-1-organization.ts @@ -1,10 +1,10 @@ import type { Construct } from 'constructs' -import type { AccountAlias } from '../types' +import type { IAccountAlias } from '../types' import * as cdk from 'aws-cdk-lib' import { P6CDKNamer } from 'p6-cdk-namer' // import { CfnOrganization } from 'aws-cdk-lib/aws-organizations' -interface OrganizationStackProps extends cdk.StackProps, AccountAlias {} +interface OrganizationStackProps extends cdk.StackProps, IAccountAlias {} export class OrganizationStack extends cdk.Stack { public readonly centralBucketArn: string diff --git a/src/stacks/network-1.ts b/src/stacks/network-1.ts index fc3906c..6b1ad74 100644 --- a/src/stacks/network-1.ts +++ b/src/stacks/network-1.ts @@ -1,9 +1,9 @@ import type { Construct } from 'constructs' -import type { AccountAlias, ShareWithOrg } from '../types' +import type { IAccountAlias, IShareWithOrg } from '../types' import * as cdk from 'aws-cdk-lib' import { P6CDKNamer } from 'p6-cdk-namer' -interface NetworkAccountStack1Props extends cdk.StackProps, AccountAlias, ShareWithOrg {} +interface NetworkAccountStack1Props extends cdk.StackProps, IAccountAlias, IShareWithOrg {} export class NetworkAccountStack1 extends cdk.Stack { constructor(scope: Construct, id: string, props: NetworkAccountStack1Props) { diff --git a/src/stacks/network-2.ts b/src/stacks/network-2.ts index 51e82d6..d68637a 100644 --- a/src/stacks/network-2.ts +++ b/src/stacks/network-2.ts @@ -1,10 +1,10 @@ import type { Construct } from 'constructs' -import type { LogarchiveBucketArn, ShareWithOrg } from './../types' +import type { ILogarchiveBucketArn, IShareWithOrg } from './../types' import * as cdk from 'aws-cdk-lib' import * as s3 from 'aws-cdk-lib/aws-s3' import { P6LzSraConfig } from '../constructs/p6-lz-sra-config' -interface NetworkAccountStack2Props extends cdk.StackProps, LogarchiveBucketArn, ShareWithOrg {} +interface NetworkAccountStack2Props extends cdk.StackProps, ILogarchiveBucketArn, IShareWithOrg {} export class NetworkAccountStack2 extends cdk.Stack { constructor(scope: Construct, id: string, props: NetworkAccountStack2Props) { diff --git a/src/stacks/prod.ts b/src/stacks/prod.ts index 94a46d2..771360f 100644 --- a/src/stacks/prod.ts +++ b/src/stacks/prod.ts @@ -1,9 +1,10 @@ import type { Construct } from 'constructs' -import type { AccountAlias } from '../types' +import type { IAccountAlias, IVpc } from '../types' import * as cdk from 'aws-cdk-lib' import { P6CDKNamer } from 'p6-cdk-namer' +import { P6LzVpc } from '../constructs/p6-lz-vpc' -interface ProdAccountStack2Props extends cdk.StackProps, AccountAlias {} +interface ProdAccountStack2Props extends cdk.StackProps, IAccountAlias, IVpc {} export class ProdAccountStack extends cdk.Stack { constructor(scope: Construct, id: string, props: ProdAccountStack2Props) { @@ -12,5 +13,10 @@ export class ProdAccountStack extends cdk.Stack { new P6CDKNamer(this, 'P6CDKNamer', { accountAlias: props.accountAlias, }) + + new P6LzVpc(this, 'P6LzVpc', { + cidr: props.cidr, + myIp: props.myIp, + }) } } diff --git a/src/stacks/qa.ts b/src/stacks/qa.ts index 75bc244..972ce29 100644 --- a/src/stacks/qa.ts +++ b/src/stacks/qa.ts @@ -1,9 +1,10 @@ import type { Construct } from 'constructs' -import type { AccountAlias } from '../types' +import type { IAccountAlias, IVpc } from '../types' import * as cdk from 'aws-cdk-lib' import { P6CDKNamer } from 'p6-cdk-namer' +import { P6LzVpc } from '../constructs/p6-lz-vpc' -interface QaAccountStack2Props extends cdk.StackProps, AccountAlias {} +interface QaAccountStack2Props extends cdk.StackProps, IAccountAlias, IVpc {} export class QaAccountStack extends cdk.Stack { constructor(scope: Construct, id: string, props: QaAccountStack2Props) { @@ -12,5 +13,10 @@ export class QaAccountStack extends cdk.Stack { new P6CDKNamer(this, 'P6CDKNamer', { accountAlias: props.accountAlias, }) + + new P6LzVpc(this, 'P6LzVpc', { + cidr: props.cidr, + myIp: props.myIp, + }) } } diff --git a/src/stacks/sandbox.ts b/src/stacks/sandbox.ts index 2cc34e3..bffd108 100644 --- a/src/stacks/sandbox.ts +++ b/src/stacks/sandbox.ts @@ -1,9 +1,10 @@ import type { Construct } from 'constructs' -import type { AccountAlias } from '../types' +import type { IAccountAlias, IVpc } from '../types' import * as cdk from 'aws-cdk-lib' import { P6CDKNamer } from 'p6-cdk-namer' +import { P6LzVpc } from '../constructs/p6-lz-vpc' -interface SandboxAccountStack2Props extends cdk.StackProps, AccountAlias {} +interface SandboxAccountStack2Props extends cdk.StackProps, IAccountAlias, IVpc {} export class SandboxAccountStack extends cdk.Stack { constructor(scope: Construct, id: string, props: SandboxAccountStack2Props) { @@ -12,5 +13,10 @@ export class SandboxAccountStack extends cdk.Stack { new P6CDKNamer(this, 'P6CDKNamer', { accountAlias: props.accountAlias, }) + + new P6LzVpc(this, 'P6LzVpc', { + cidr: props.cidr, + myIp: props.myIp, + }) } } diff --git a/src/stacks/shared-1.ts b/src/stacks/shared-1.ts index 12107b9..5aa6a82 100644 --- a/src/stacks/shared-1.ts +++ b/src/stacks/shared-1.ts @@ -1,9 +1,9 @@ import type { Construct } from 'constructs' -import type { AccountAlias, ShareWithOrg } from '../types' +import type { IAccountAlias, IShareWithOrg } from '../types' import * as cdk from 'aws-cdk-lib' import { P6CDKNamer } from 'p6-cdk-namer' -interface SharedAccountStack1Props extends cdk.StackProps, AccountAlias, ShareWithOrg {} +interface SharedAccountStack1Props extends cdk.StackProps, IAccountAlias, IShareWithOrg {} export class SharedAccountStack1 extends cdk.Stack { constructor(scope: Construct, id: string, props: SharedAccountStack1Props) { diff --git a/src/stacks/shared-2.ts b/src/stacks/shared-2.ts index 929916e..73a463c 100644 --- a/src/stacks/shared-2.ts +++ b/src/stacks/shared-2.ts @@ -1,10 +1,10 @@ import type { Construct } from 'constructs' -import type { LogarchiveBucketArn, ShareWithOrg } from '../types' +import type { ILogarchiveBucketArn, IShareWithOrg } from '../types' import * as cdk from 'aws-cdk-lib' import * as s3 from 'aws-cdk-lib/aws-s3' import { P6LzSraConfig } from '../constructs/p6-lz-sra-config' -interface SharedAccountStack2Props extends cdk.StackProps, LogarchiveBucketArn, ShareWithOrg {} +interface SharedAccountStack2Props extends cdk.StackProps, ILogarchiveBucketArn, IShareWithOrg {} export class SharedAccountStack2 extends cdk.Stack { constructor(scope: Construct, id: string, props: SharedAccountStack2Props) { diff --git a/src/types.ts b/src/types.ts index 728de35..7fe3a02 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,7 +1,8 @@ import type * as cdk from 'aws-cdk-lib' +import type { IIpAddresses, IPeer } from 'aws-cdk-lib/aws-ec2' import type * as s3 from 'aws-cdk-lib/aws-s3' -export interface AccountIds { +export interface IAccountIds { auditAccountId: string devAccountId: string logarchiveAccountId: string @@ -13,18 +14,23 @@ export interface AccountIds { sharedAccountId: string } -export interface AccountAlias { +export interface IAccountAlias { accountAlias: string } -export interface ShareWithOrg { +export interface IShareWithOrg { principals: string[] } -export interface LogarchiveBucket { +export interface ILogarchiveBucket { centralBucket: s3.IBucket } -export interface LogarchiveBucketArn { +export interface ILogarchiveBucketArn { centralBucketArn: cdk.Arn } + +export interface IVpc { + cidr: IIpAddresses + myIp: IPeer +}