Skip to content

Commit

Permalink
Merge branch 'main' into AMIBackup
Browse files Browse the repository at this point in the history
  • Loading branch information
alinadima authored Oct 10, 2023
2 parents 323cb13 + 579830a commit a2c569e
Show file tree
Hide file tree
Showing 13 changed files with 504 additions and 1 deletion.
16 changes: 16 additions & 0 deletions .github/workflows/shellcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: shellcheck
on:
push:
branches: ["**"]
pull_request:
branches: ["**"]
jobs:
Run-Pre-Commit:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v2
- name: Install shellcheck
run: sudo apt-get install shellcheck
- name: Run shellcheck
run: shellcheck assets/*.sh
1 change: 1 addition & 0 deletions lib/build-image-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class BuildImageDataStack extends cdk.Stack {
versioned: true,
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
enforceSSL: true,
});

const dataBucketDeploymentRole = new iam.Role(
Expand Down
10 changes: 10 additions & 0 deletions lib/network.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs';

/**
* The network resources to run the pipeline in.
Expand All @@ -18,5 +19,14 @@ export class PipelineNetworkStack extends cdk.Stack {
this.vpc = new ec2.Vpc(this, 'PipelineVpc', {
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
});

new ec2.FlowLog(this, 'VPCFlowLogs', {
resourceType: ec2.FlowLogResourceType.fromVpc(this.vpc),
destination: ec2.FlowLogDestination.toCloudWatchLogs(
new LogGroup(this, 'LogGroup', {
retention: RetentionDays.ONE_YEAR,
})
),
});
}
}
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"typedoc": "^0.24.8",
"typescript": "~5.0.4"
"typescript": "~5.0.4",
"cdk-nag": "^2.27.131"
},
"peerDependencies": {
"aws-cdk-lib": "2.86.0",
Expand Down
34 changes: 34 additions & 0 deletions test/__snapshots__/build-image-data.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,40 @@ exports[`Build Image Data Snapshot 1`] = `
},
"PolicyDocument": {
"Statement": [
{
"Action": "s3:*",
"Condition": {
"Bool": {
"aws:SecureTransport": "false",
},
},
"Effect": "Deny",
"Principal": {
"AWS": "*",
},
"Resource": [
{
"Fn::GetAtt": [
"BuildImageDataBucketE6A8BC04",
"Arn",
],
},
{
"Fn::Join": [
"",
[
{
"Fn::GetAtt": [
"BuildImageDataBucketE6A8BC04",
"Arn",
],
},
"/*",
],
],
},
],
},
{
"Action": [
"s3:GetBucket*",
Expand Down
85 changes: 85 additions & 0 deletions test/__snapshots__/network.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ exports[`Pipeline Networking Snapshot 1`] = `
},
},
"Resources": {
"LogGroupF5B46931": {
"DeletionPolicy": "Retain",
"Properties": {
"RetentionInDays": 365,
},
"Type": "AWS::Logs::LogGroup",
"UpdateReplacePolicy": "Retain",
},
"PipelineVpc0543904A": {
"Properties": {
"CidrBlock": "10.0.0.0/16",
Expand Down Expand Up @@ -536,6 +544,83 @@ exports[`Pipeline Networking Snapshot 1`] = `
},
"Type": "AWS::EC2::VPCGatewayAttachment",
},
"VPCFlowLogsFlowLogD2BDB2A5": {
"Properties": {
"DeliverLogsPermissionArn": {
"Fn::GetAtt": [
"VPCFlowLogsIAMRoleFF7B3C14",
"Arn",
],
},
"LogDestinationType": "cloud-watch-logs",
"LogGroupName": {
"Ref": "LogGroupF5B46931",
},
"ResourceId": {
"Ref": "PipelineVpc0543904A",
},
"ResourceType": "VPC",
"TrafficType": "ALL",
},
"Type": "AWS::EC2::FlowLog",
},
"VPCFlowLogsIAMRoleDefaultPolicy0D9292CF": {
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams",
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"LogGroupF5B46931",
"Arn",
],
},
},
{
"Action": "iam:PassRole",
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"VPCFlowLogsIAMRoleFF7B3C14",
"Arn",
],
},
},
],
"Version": "2012-10-17",
},
"PolicyName": "VPCFlowLogsIAMRoleDefaultPolicy0D9292CF",
"Roles": [
{
"Ref": "VPCFlowLogsIAMRoleFF7B3C14",
},
],
},
"Type": "AWS::IAM::Policy",
},
"VPCFlowLogsIAMRoleFF7B3C14": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "vpc-flow-logs.amazonaws.com",
},
},
],
"Version": "2012-10-17",
},
},
"Type": "AWS::IAM::Role",
},
},
"Rules": {
"CheckBootstrapVersion": {
Expand Down
76 changes: 76 additions & 0 deletions test/build-image-data-nag.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import * as cdk from 'aws-cdk-lib';
import { BuildImageDataStack } from '../lib/build-image-data';

import { Annotations, Match } from 'aws-cdk-lib/assertions';
import { App, Aspects, Stack } from 'aws-cdk-lib';
import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag';

describe('BuildImageDataStack cdk-nag AwsSolutions Pack', () => {
let stack: Stack;
let app: App;

beforeAll(() => {
// GIVEN
app = new App();
const props = {
bucketName: 'test-bucket',
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
env: { account: '111111111111', region: 'eu-central-1' },
};
stack = new BuildImageDataStack(app, 'MyTestStack', props);

NagSuppressions.addStackSuppressions(stack, [
{
id: 'AwsSolutions-IAM4',
reason: 'TODO: Re-evaluate managed policies per resources.',
},
{
id: 'AwsSolutions-IAM5',
reason: 'TODO: Re-evaluate "*" per resources.',
},
]);

NagSuppressions.addResourceSuppressionsByPath(
stack,
'/MyTestStack/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Resource',
[
{
id: 'AwsSolutions-L1',
reason: 'This Lambda function is 3rd Party (from CDK libs)',
},
]
);

NagSuppressions.addResourceSuppressionsByPath(
stack,
'/MyTestStack/BuildImageDataBucket/Resource',
[
{
id: 'AwsSolutions-S1',
reason: 'TODO: Add Access Logging',
},
]
);

// WHEN
Aspects.of(stack).add(new AwsSolutionsChecks({ verbose: true }));
});

// THEN
test('No unsuppressed Warnings', () => {
const warnings = Annotations.fromStack(stack).findWarning(
'*',
Match.stringLikeRegexp('AwsSolutions-.*')
);
expect(warnings).toHaveLength(0);
});

test('No unsuppressed Errors', () => {
const errors = Annotations.fromStack(stack).findError(
'*',
Match.stringLikeRegexp('AwsSolutions-.*')
);
expect(errors).toHaveLength(0);
});
});
73 changes: 73 additions & 0 deletions test/build-image-pipeline-nag.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as cdk from 'aws-cdk-lib';
import {
BuildImagePipelineStack,
ImageKind,
} from '../lib/build-image-pipeline';
import { Repository } from 'aws-cdk-lib/aws-ecr';
import { Bucket } from 'aws-cdk-lib/aws-s3';

import { Annotations, Match } from 'aws-cdk-lib/assertions';
import { App, Aspects, Stack } from 'aws-cdk-lib';
import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag';

describe('BuildImagePipelineStack cdk-nag AwsSolutions Pack', () => {
let stack: Stack;
let app: App;

beforeAll(() => {
// GIVEN
const env = { account: '111111111111', region: 'eu-central-1' };
app = new cdk.App();
const repoStack = new cdk.Stack(app, 'RepoStack', { env });
const repository = new Repository(repoStack, 'Repository', {});
const dataBucket = new Bucket(repoStack, 'Bucket', {});

const props = {
env,
imageKind: ImageKind.Ubuntu22_04,
repository,
dataBucket,
};

stack = new BuildImagePipelineStack(repoStack, 'MyTestStack', props);
NagSuppressions.addStackSuppressions(stack, [
{
id: 'AwsSolutions-CB3',
reason: 'Privilege Mode Required To Build Docker Containers.',
},
{
id: 'AwsSolutions-IAM5',
reason: 'TODO: Re-evaluate "*" per resources.',
},
{
id: 'AwsSolutions-S1',
reason: 'TODO: Re-evaluate bucket access logging.',
},
{
id: 'AwsSolutions-KMS5',
reason: 'TODO: Re-evaluate key rotation.',
},
]);
// WHEN
Aspects.of(stack).add(new AwsSolutionsChecks({ verbose: true }));
});

// THEN
test('No unsuppressed Warnings', () => {
const warnings = Annotations.fromStack(stack).findWarning(
'*',
Match.stringLikeRegexp('AwsSolutions-.*')
);

expect(warnings).toHaveLength(0);
});

test('No unsuppressed Errors', () => {
const errors = Annotations.fromStack(stack).findError(
'*',
Match.stringLikeRegexp('AwsSolutions-.*')
);

expect(errors).toHaveLength(0);
});
});
Loading

0 comments on commit a2c569e

Please sign in to comment.