Skip to content

Commit

Permalink
feat: port changes from HVP 1.3.6
Browse files Browse the repository at this point in the history
  • Loading branch information
gmuslia committed May 15, 2024
1 parent 27242a6 commit 7344049
Show file tree
Hide file tree
Showing 14 changed files with 551 additions and 393 deletions.
149 changes: 66 additions & 83 deletions NOTICE

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions OSS_License_Summary.csv
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"BSD-3-Clause","18"
"BlueOak-1.0.0","2"
"CC-BY-4.0","1"
"ISC","53"
"ISC","54"
"MIT*","2"
"MIT","530"
"MIT","529"
"Python-2.0","1"
#########################
# Python module: src/lambda-layer/common/Pipfile
Expand Down
18 changes: 11 additions & 7 deletions bin/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ import { NagUtils } from '../utils/suppressions';

const app = new cdk.App();

const repositoryStack = new RepositoryStack(app, `${AppConfig.applicationName}Repository`, {
env: { account: AppConfig.deploymentAccounts.RES, region: AppConfig.region },
applicationName: AppConfig.applicationName,
applicationQualifier: AppConfig.applicationQualifier,
repositoryConfig: AppConfig.repositoryConfig,
});

new ComplianceLogBucketStack(app, `${AppConfig.applicationName}ComplianceLogBucketStack`, {
complianceLogBucketName: AppConfig.complianceLogBucketName.RES,
});
Expand All @@ -44,6 +37,17 @@ const vpcStack = new VPCStack(app, `${AppConfig.applicationName}VPCStack`, {
flowLogsBucketName: AppConfig.complianceLogBucketName.RES,
});

const repositoryStack = new RepositoryStack(app, `${AppConfig.applicationName}Repository`, {
env: { account: AppConfig.deploymentAccounts.RES, region: AppConfig.region },
applicationName: AppConfig.applicationName,
applicationQualifier: AppConfig.applicationQualifier,
repositoryConfig: AppConfig.repositoryConfig,
vpcProps: (vpcStack.vpc ? {
vpc: vpcStack.vpc,
proxy: AppConfig.proxy,
} : undefined),
});

const encryptionStack = new EncryptionStack(app, `${AppConfig.applicationName}EncryptionStack`, {
env: { account: AppConfig.deploymentAccounts.RES, region: AppConfig.region },
applicationName: AppConfig.applicationName,
Expand Down
84 changes: 55 additions & 29 deletions lib/cdk-pipeline/core/CDKPipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import * as iam from 'aws-cdk-lib/aws-iam';
import * as pipelines from 'aws-cdk-lib/pipelines';
import { NagSuppressions } from 'cdk-nag';
import { Construct, IConstruct } from 'constructs';
import * as _ from 'lodash';
import { CodeGuruSecurityStep, CodeGuruSeverityThreshold } from './constructs/CodeGuruSecurityStepConstruct';

interface Props extends PipelineProps {
Expand All @@ -17,7 +16,7 @@ interface Props extends PipelineProps {
rolePolicies?: iam.PolicyStatement[];
}

export interface VpcProps {
export interface IVpcProps {
vpc: ec2.IVpc;
proxy?: {
noProxy: string[];
Expand All @@ -32,7 +31,7 @@ export interface PipelineProps {
isDockerEnabledForSynth?: boolean;
buildImage?: codebuild.IBuildImage;
codeGuruScanThreshold?: CodeGuruSeverityThreshold;
vpcProps?: VpcProps;
vpcProps?: IVpcProps;
pipelineVariables?: {[key in string]: string};
primaryOutputDirectory: string;
}
Expand All @@ -51,7 +50,6 @@ class CodeBuildAspect implements cdk.IAspect {
export class CDKPipeline extends pipelines.CodePipeline {
static readonly pipelineCommands: string[] =
[
'./scripts/proxy.sh',
'./scripts/check-audit.sh',
'. ./scripts/warming.sh',
'./scripts/build.sh',
Expand Down Expand Up @@ -86,7 +84,7 @@ export class CDKPipeline extends pipelines.CodePipeline {
primaryOutputDirectory: props.primaryOutputDirectory,
}),
codeBuildDefaults: {
...CDKPipeline.generateVPCCodeBuildDefaults(scope, props.vpcProps),
...CDKPipeline.generateVPCCodeBuildDefaults(props.vpcProps),
partialBuildSpec: CDKPipeline.getPartialBuildSpec(props.vpcProps),
buildEnvironment: {
buildImage: props.buildImage,
Expand All @@ -103,51 +101,61 @@ export class CDKPipeline extends pipelines.CodePipeline {
}

static getDefaultPartialBuildSpec() {
return {
return codebuild.BuildSpec.fromObject({
version: '0.2',
env: {
shell: 'bash',
},
};
});
}

static getPartialBuildSpec(vpcProps?: VpcProps) {
static getPartialBuildSpec(vpcProps?: IVpcProps) {
const buildSpec = CDKPipeline.getDefaultPartialBuildSpec();

if (vpcProps?.proxy?.proxySecretArn) {
// deep merge with
_.merge(buildSpec, {
const {
proxy: {
noProxy,
proxySecretArn,
proxyTestUrl,
},
} = vpcProps;

// Construct environment variables
const envVariables = {
NO_PROXY: noProxy.join(', '),
AWS_STS_REGIONAL_ENDPOINTS: 'regional',
};

// Construct secrets manager object
const secretsManager = {
PROXY_USERNAME: `${proxySecretArn}:username`,
PROXY_PASSWORD: `${proxySecretArn}:password`,
HTTP_PROXY_PORT: `${proxySecretArn}:http_proxy_port`,
HTTPS_PROXY_PORT: `${proxySecretArn}:https_proxy_port`,
PROXY_DOMAIN: `${proxySecretArn}:proxy_domain`,
};

// Merge the constructed objects with existing buildSpec
return codebuild.mergeBuildSpecs(buildSpec, codebuild.BuildSpec.fromObject({
env: {
'variables': {
NO_PROXY: vpcProps.proxy.noProxy.join(', '),
AWS_STS_REGIONAL_ENDPOINTS: 'regional',
},
'secrets-manager': {
PROXY_USERNAME: vpcProps.proxy.proxySecretArn.concat(':username'),
PROXY_PASSWORD: vpcProps.proxy.proxySecretArn.concat(':password'),
HTTP_PROXY_PORT: vpcProps.proxy.proxySecretArn.concat(':http_proxy_port'),
HTTPS_PROXY_PORT: vpcProps.proxy.proxySecretArn.concat(':https_proxy_port'),
PROXY_DOMAIN: vpcProps.proxy.proxySecretArn.concat(':proxy_domain'),
},
'variables': envVariables,
'secrets-manager': secretsManager,
},
phases: {
install: {
commands: [
'export HTTP_PROXY="http://$PROXY_USERNAME:$PROXY_PASSWORD@$PROXY_DOMAIN:$HTTP_PROXY_PORT"',
'export HTTPS_PROXY="https://$PROXY_USERNAME:$PROXY_PASSWORD@$PROXY_DOMAIN:$HTTPS_PROXY_PORT"',
'echo "--- Proxy Test ---"',
`curl -Is --connect-timeout 5 ${vpcProps.proxy.proxyTestUrl} | grep "HTTP/"`,
CDKPipeline.getInstallCommands(vpcProps),
],
},
},
});

}));
}

return codebuild.BuildSpec.fromObject(buildSpec);
return buildSpec;
}

static generateVPCCodeBuildDefaults(scope: Construct, vpcProps?: VpcProps): pipelines.CodeBuildOptions | {} {
static generateVPCCodeBuildDefaults(vpcProps?: IVpcProps): pipelines.CodeBuildOptions | {} {
if (!vpcProps) return {};

return {
Expand All @@ -156,6 +164,24 @@ export class CDKPipeline extends pipelines.CodePipeline {
};
}

public static getInstallCommands(vpcProps: IVpcProps) : string {
return 'export HTTP_PROXY="http://$PROXY_USERNAME:$PROXY_PASSWORD@$PROXY_DOMAIN:$HTTP_PROXY_PORT"; ' +
'export HTTPS_PROXY="https://$PROXY_USERNAME:$PROXY_PASSWORD@$PROXY_DOMAIN:$HTTPS_PROXY_PORT"; ' +
'echo "--- Proxy Test ---"; ' +
`curl -Is --connect-timeout 5 ${vpcProps!.proxy!.proxyTestUrl} | grep "HTTP/"; ` +
'if [ -f /var/run/docker.pid ]; then ' +
'echo "--- Configuring docker env ---" ' +
'&& mkdir ~/.docker/ ' +
'&& echo -n "{\\"proxies\\": {\\"default\\": {\\"httpProxy\\": \\"$HTTP_PROXY\\",\\"httpsProxy\\": \\"$HTTPS_PROXY\\",\\"noProxy\\": \\"$NO_PROXY\\"}}}" > ~/.docker/config.json ' +
'&& cat ~/.docker/config.json ' +
'&& echo "Kill and restart the docker daemon so that it reads the PROXY env variables" ' +
'&& kill "$(cat /var/run/docker.pid)" ' +
'&& while kill -0 "$(cat /var/run/docker.pid)" ; do sleep 1 ; done ' +
'&& /usr/local/bin/dockerd-entrypoint.sh > /dev/null 2>&1 ' +
'&& echo "--- Docker daemon restarted ---"; ' +
'fi';
}

public buildPipeline(): void {
super.buildPipeline();

Expand Down
22 changes: 18 additions & 4 deletions lib/stacks/app/MonitoringStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,25 @@ export class MonitoringStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: Props) {
super(scope, id, props);

const encryptionKey = new kms.Key(this, 'KMSKey', {
enableKeyRotation: true,
alias: `${props.applicationName}-${props.stageName}-Monitoring-key`,
});

const myCustomPolicy = new iam.PolicyStatement({
actions: [
'kms:GenerateDataKey',
'kms:Describe*',
'kms:Decrypt*',
],
principals: [new iam.ServicePrincipal('cloudwatch.amazonaws.com')],
resources: ['*'],
});

encryptionKey.addToResourcePolicy(myCustomPolicy);

const monitoringTopic = new sns.Topic(this, 'MonitoringTopic', {
masterKey: new kms.Key(this, 'KMSKey', {
enableKeyRotation: true,
alias: `${props.applicationName}-${props.stageName}-Monitoring-key`,
}),
masterKey: encryptionKey,
});

monitoringTopic.grantPublish(new iam.AccountRootPrincipal);
Expand Down
6 changes: 5 additions & 1 deletion lib/stacks/app/S3BucketStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import * as cdk from 'aws-cdk-lib';
import * as kms from 'aws-cdk-lib/aws-kms';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
import { STAGE } from '../../../config/Types';
import { S3Bucket } from '../../cdk-pipeline/core/S3Bucket';
Expand All @@ -15,10 +16,13 @@ interface Props extends cdk.StackProps {
}

export class S3BucketStack extends cdk.Stack {

readonly bucket: s3.IBucket;

constructor(scope: Construct, id: string, props: Props) {
super(scope, id, props);

new S3Bucket(this, 'S3Bucket', {
this.bucket = new S3Bucket(this, 'S3Bucket', {
applicationQualifier: props.applicationQualifier,
stageName: props.stageName,
bucketName: props.bucketName,
Expand Down
3 changes: 3 additions & 0 deletions lib/stacks/core/RepositoryStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { Construct } from 'constructs';
import { CodeCommitRepositoryConstruct } from './constructs/CodeCommitRepositoryConstruct';
import { CodeStarConnectionConstruct } from './constructs/CodeStarConnectionConstruct';
import { IRepositoryConfig } from '../../../config/Types';
import { IVpcProps } from '../../cdk-pipeline/core/CDKPipeline';

interface RepositoryProps extends cdk.StackProps {
applicationName: string;
applicationQualifier: string;
repositoryConfig: IRepositoryConfig;
vpcProps?: IVpcProps;
}

export class RepositoryStack extends cdk.Stack {
Expand All @@ -36,6 +38,7 @@ export class RepositoryStack extends cdk.Stack {
applicationName: props.applicationName,
applicationQualifier: props.applicationQualifier,
...props.repositoryConfig.CODECOMMIT,
vpcProps: props.vpcProps,
}).pipelineInput;
this.repositoryBranch = props.repositoryConfig.CODECOMMIT.branch;
this.pipelineEnvVars = {};
Expand Down
48 changes: 33 additions & 15 deletions lib/stacks/core/constructs/CodeCommitRepositoryConstruct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import * as nag from 'cdk-nag';
import { Construct } from 'constructs';
import { CodeCommitRepositoryAspects } from './CodeCommitRepositoryAspects';
import { ICodeCommitConfig } from '../../../../config/Types';
import { CDKPipeline } from '../../../cdk-pipeline/core/CDKPipeline';
import { CDKPipeline, IVpcProps } from '../../../cdk-pipeline/core/CDKPipeline';
import { SSMParameterStack } from '../SSMParameterStack';

interface Props extends ICodeCommitConfig {
applicationName: string;
applicationQualifier: string;
vpcProps?: IVpcProps;
}

export class CodeCommitRepositoryConstruct extends Construct {
Expand Down Expand Up @@ -59,22 +60,25 @@ export class CodeCommitRepositoryConstruct extends Construct {
repository,
});

const buildSpec = CDKPipeline.getPartialBuildSpec(props.vpcProps);

codebuild.mergeBuildSpecs(buildSpec, codebuild.BuildSpec.fromObject({
phases: {
install: {
commands: [
`export CDK_QUALIFIER=${props.applicationQualifier}`,
],
},
build: {
commands: CDKPipeline.pipelineCommands,
},
},
}));

const pullRequestCheck = new PullRequestCheck(this, 'PullRequestCheck', {
repository,
buildSpec: codebuild.BuildSpec.fromObject({
version: '0.2',
phases: {
install: {
commands: [
...CDKPipeline.installCommands,
`export CDK_QUALIFIER=${props.applicationQualifier}`,
],
},
build: {
commands: CDKPipeline.pipelineCommands,
},
},
}),
buildSpec: codebuild.BuildSpec.fromObject(buildSpec),
vpc: props.vpcProps?.vpc,
privileged: props.codeBuildConfig.isPrivileged,
buildImage: props.codeBuildConfig.buildImage,
});
Expand All @@ -94,6 +98,20 @@ export class CodeCommitRepositoryConstruct extends Construct {
pullRequestCheck.addToRolePolicy(
SSMParameterStack.getGetParameterPolicyStatement(cdk.Stack.of(this).account, cdk.Stack.of(this).region, props.applicationQualifier ),
);

if (props.vpcProps?.proxy?.proxySecretArn) {
pullRequestCheck.addToRolePolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: [
'secretsmanager:GetSecretValue',
],
resources: [
props.vpcProps.proxy.proxySecretArn,
],
}),
);
}
});

cdk.Aspects.of(cdk.Stack.of(this)).add(
Expand Down
Loading

0 comments on commit 7344049

Please sign in to comment.