Skip to content

Commit

Permalink
fix: deployment resolution (#11492)
Browse files Browse the repository at this point in the history
* fix: resolve deployment with cdk 2.162.1

* fix: resolve OAC for distro

* chore: linting

* fix: remove bastion ec2

* feat: add dev url for pipeline

* fix: resolve tests for pipeline info

* fix: corrected mock within test

* chore: remove files from coverage
  • Loading branch information
bashleigh authored Nov 15, 2024
1 parent 56a0d99 commit 08d1d81
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 75 deletions.
51 changes: 33 additions & 18 deletions packages/deployment-service/cdk/lib/cdk-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { createLambda } from './create-lambda'
import { createS3Buckets } from './create-S3-bucket'
import { createSqsQueues, QueueNames } from './create-sqs'
import { createPolicies } from './create-policies'
import { Role } from 'aws-cdk-lib/aws-iam'
import { Effect, Role } from 'aws-cdk-lib/aws-iam'
import config from '../../config.json'
import * as cdk from 'aws-cdk-lib'

Expand Down Expand Up @@ -71,11 +71,21 @@ export const createStack = async () => {

const api = createApi(stack, 'apigateway', undefined)
const vpc = createVpc(stack, 'vpc')
const buckets = createS3Buckets(stack, usercodeStack, envStage)
const buckets = createS3Buckets(usercodeStack, envStage)
const queues = createSqsQueues(stack)
const database = createDatabase(stack, 'database', databaseName, vpc)
const secretManager = database.secret

const AOC = new cdk.aws_cloudfront.CfnOriginAccessControl(usercodeStack, 's3-origin', {
originAccessControlConfig: {
name: 'distro-to-s3',
originAccessControlOriginType: 's3',
signingBehavior: 'always',
signingProtocol: 'sigv4',
description: 'Allow distros to access S3',
},
})

if (!secretManager) {
throw new Error('Failed to create rds secret')
}
Expand All @@ -101,7 +111,12 @@ export const createStack = async () => {
const functionSetups: { [s: string]: FunctionSetup } = {
sqs: {
handler: createFileLoc('sqs', 'handle'),
policies: [...policies.commonBackendPolicies, policies.cloudFrontPolicy, policies.route53Policy],
policies: [
...policies.commonBackendPolicies,
policies.cloudFrontPolicy,
policies.route53Policy,
policies.originAccessControlPolicy,
],
queues: [
queues[QueueNames.CODEBUILD_EXECUTOR],
queues[QueueNames.CODEBUILD_VERSION_DEPLOY],
Expand Down Expand Up @@ -239,23 +254,23 @@ export const createStack = async () => {
* is to add the migration script to a second stack which required the first stack
*/

// const migrationHandler = createLambda({
// stack,
// name: 'cloud-deployment-migration',
// entrypoint: 'bundle/migration-run.zip',
// handler: createFileLoc('migration-run', 'migrationRun'),
// runtime: aws_lambda.Runtime.NODEJS_18_X,
// env,
// vpc,
// })
const migrationHandler = createLambda({
stack,
name: 'cloud-deployment-migration',
entrypoint: 'bundle/migration-run.zip',
handler: createFileLoc('migration-run', 'migrationRun'),
runtime: aws_lambda.Runtime.NODEJS_18_X,
env,
vpc,
})

// policies.commonBackendPolicies.forEach((policy) => migrationHandler.addToRolePolicy(policy))
policies.commonBackendPolicies.forEach((policy) => migrationHandler.addToRolePolicy(policy))

// Object.values(policies)
// .filter((policy) => policy instanceof PolicyStatement)
// .forEach((policy) => migrationHandler.addToRolePolicy(policy as PolicyStatement))
Object.values(policies)
.filter((policy) => policy instanceof PolicyStatement)
.forEach((policy) => migrationHandler.addToRolePolicy(policy as PolicyStatement))

// const numberOfMigrations = await getNumberOfMigrations()
const numberOfMigrations = await getNumberOfMigrations()

// createStackEventHandler(stack, 'migration-event', migrationHandler, `${numberOfMigrations}`)
createStackEventHandler(stack, 'migration-event', migrationHandler, `${numberOfMigrations}`)
}
79 changes: 56 additions & 23 deletions packages/deployment-service/cdk/lib/create-S3-bucket.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Stack, Bucket, BucketOptions, PolicyStatement } from '@reapit/ts-scripts/src/cdk'
import { aws_s3, PhysicalName, aws_iam } from 'aws-cdk-lib'
import { aws_s3, PhysicalName, aws_iam, Stack } from 'aws-cdk-lib'
import { ServicePrincipal } from 'aws-cdk-lib/aws-iam'

export enum BucketNames {
LIVE = 'v2-cloud-deployment-live',
Expand All @@ -8,20 +8,33 @@ export enum BucketNames {
REPO_CACHE = 'v2-cloud-deployment-repo-cache',
}

export const createBucket = (stack: Stack, bucketName: string, options?: BucketOptions): aws_s3.Bucket => {
type BucketOptions = {
public?: boolean
get?: boolean
list?: boolean
put?: boolean
stack?: Stack
}

export const createBucket = ({
stack,
bucketName,
options,
}: {
stack: Stack
bucketName: string
options?: BucketOptions
}): aws_s3.Bucket => {
const bucket = new aws_s3.Bucket(options?.stack || stack, bucketName, {
publicReadAccess: true,
websiteIndexDocument: options?.public ? 'index.html' : undefined,
bucketName: bucketName || PhysicalName.GENERATE_IF_NEEDED,
// blockPublicAccess: aws_s3.BlockPublicAccess.BLOCK_ALL,
// accessControl: aws_s3.BucketAccessControl.PRIVATE,
// objectOwnership: aws_s3.ObjectOwnership.OBJECT_WRITER,
blockPublicAccess: new aws_s3.BlockPublicAccess({
blockPublicAcls: false,
ignorePublicAcls: false,
blockPublicAccess: {
blockPublicPolicy: false,
blockPublicAcls: false,
restrictPublicBuckets: false,
}),
ignorePublicAcls: false,
},
publicReadAccess: false,
})

const actions: string[] = []
Expand All @@ -36,17 +49,37 @@ export const createBucket = (stack: Stack, bucketName: string, options?: BucketO
}

bucket.addToResourcePolicy(
new PolicyStatement({
new aws_iam.PolicyStatement({
effect: aws_iam.Effect.ALLOW,
actions,
resources: [bucket.arnForObjects('*')],
principals: [new aws_iam.ArnPrincipal('*')],
}),
)

// allows cloudfront to access this bucket
bucket.addToResourcePolicy(
new aws_iam.PolicyStatement({
effect: aws_iam.Effect.ALLOW,
actions: ['s3:Get*'],
resources: [bucket.arnForObjects('*')],
principals: [new ServicePrincipal('cloudfront.amazonaws.com')],
}),
)

bucket.addToResourcePolicy(
new aws_iam.PolicyStatement({
effect: aws_iam.Effect.ALLOW,
actions: ['s3:Get*'],
resources: [bucket.arnForObjects('*')],
principals: [new ServicePrincipal('codebuild.amazonaws.com')],
}),
)

return bucket
}

export const createS3Buckets = (stack: Stack, usercodeStack: Stack, envStage: string): Record<BucketNames, Bucket> => {
export const createS3Buckets = (usercodeStack: Stack, envStage: string): Record<BucketNames, aws_s3.IBucket> => {
const bucketOptions: {
[k in BucketNames]: BucketOptions
} = {
Expand All @@ -55,32 +88,32 @@ export const createS3Buckets = (stack: Stack, usercodeStack: Stack, envStage: st
get: true,
list: true,
put: true,
stack: usercodeStack,
},
[BucketNames.LOG]: {
put: true,
stack: usercodeStack,
},
[BucketNames.REPO_CACHE]: {
put: true,
get: true,
stack: usercodeStack,
},
[BucketNames.VERSION]: {
get: true,
list: true,
put: true,
stack: usercodeStack,
},
}

return (Object.keys(bucketOptions) as Array<BucketNames>).reduce<{ [k in BucketNames]: Bucket }>(
return (Object.keys(bucketOptions) as Array<BucketNames>).reduce<{ [k in BucketNames]: aws_s3.IBucket }>(
(buckets, bucketName) => {
buckets[bucketName] = createBucket(
bucketOptions[bucketName].stack || stack,
`${bucketName}-${envStage}`,
bucketOptions[bucketName],
)
// const existingBucket =
// Bucket.fromBucketName(usercodeStack, `lookup-${bucketName}`, `${bucketName}-${envStage}`)

// buckets[bucketName] = existingBucket ?? createBucket({
buckets[bucketName] = createBucket({
stack: usercodeStack,
bucketName: `${bucketName}-${envStage}`,
options: bucketOptions[bucketName],
})
return buckets
},
{} as any,
Expand Down
14 changes: 12 additions & 2 deletions packages/deployment-service/cdk/lib/create-policies.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Project, ISecret, Effect, PolicyStatement, Bucket, Stack, Topic } from '@reapit/ts-scripts/src/cdk'
import { Project, ISecret, Effect, PolicyStatement, Stack, Topic } from '@reapit/ts-scripts/src/cdk'
import { AccountPrincipal, ArnPrincipal, CompositePrincipal, Policy, Role } from 'aws-cdk-lib/aws-iam'
import config from '../../config.json'
import { aws_sqs as sqs } from 'aws-cdk-lib'
import { BucketNames } from './create-S3-bucket'
import { IBucket } from 'aws-cdk-lib/aws-s3'

export enum PolicyNames {
// lambdaInvoke = 'lambdaInvoke',
Expand All @@ -12,6 +13,7 @@ export enum PolicyNames {
sqsPolices = 'sqsPolicies',
secretManagerPolicy = 'secretManagerPolicy',
S3BucketPolicy = 'S3BucketPolicy',
originAccessControlPolicy = 'originAccessControlPolicy',
}

type namedPolicyType = {
Expand All @@ -32,7 +34,7 @@ export const createPolicies = ({
codebuildSnsTopic,
githubPemSecretArn,
}: {
buckets: { [s: string]: Bucket }
buckets: { [s: string]: IBucket }
queues: { [s: string]: sqs.IQueue }
secretManager: ISecret
codeBuild: Project
Expand Down Expand Up @@ -164,6 +166,12 @@ export const createPolicies = ({
],
})

const originAccessControlPolicy = new PolicyStatement({
actions: ['cloudfront:ListOriginAccessControls'],
effect: Effect.ALLOW,
resources: ['*'],
})

// create a policy that allows the lambda to do what it needs to do in the usercode stack
const usercodePolicy = new Policy(usercodeStack, 'UsercodePolicy')
usercodePolicy.addStatements(
Expand All @@ -173,6 +181,7 @@ export const createPolicies = ({
codebuildSnssubscriptionPolicy,
codebuildExecPolicy,
parameterStorePolicy,
originAccessControlPolicy,
)
const usercodeStackRoleName = `${usercodeStack.stackName}-UsercodeStackRole`
// create a role that lambdas can assume in the usercode stack, with the policy we just created
Expand Down Expand Up @@ -216,6 +225,7 @@ export const createPolicies = ({
commonBackendPolicies,
codebuildExecPolicy,
cloudFrontPolicy,
originAccessControlPolicy,
route53Policy,
sqsPolicies,
secretManagerPolicy,
Expand Down
10 changes: 9 additions & 1 deletion packages/deployment-service/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ module.exports = {
testPathIgnorePatterns: ['<rootDir>/dist'],
collectCoverageFrom: ['<rootDir>/src/**/*.ts'],
coverageDirectory: './src/tests/coverage',
coveragePathIgnorePatterns: ['<rootDir>[/\\\\](node_modules|src/types|src/tests|src/scripts)[/\\\\]', '.d.ts'],
coveragePathIgnorePatterns: [
'<rootDir>[/\\\\](node_modules|src/types|src/tests|src/scripts)[/\\\\]',
'.d.ts',
'src/http.ts',
'src/sqs.ts',
'src/sns.ts',
'src/local-http.ts',
'src/migration-run.ts',
],
reporters: ['default', 'github-actions'],
coverageThreshold: {
global: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export class DeployProvider {
Bucket: process.env.DEPLOYMENT_LIVE_BUCKET_NAME as string,
Key: `${prefix}/${fileName}`,
Body: buffer,
ACL: 'public-read',
// ACL: 'public-read',
ContentType: mimeType,
Metadata: {
['Content-Type']: mimeType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PipelineSetupWorkflow } from '../pipeline-setup-workflow'
import { PusherProvider, SqsProvider } from '../../events'
import { PipelineProvider } from '../pipeline-provider'
import { SQS, S3 } from 'aws-sdk'
import { CloudFrontClient } from '@aws-sdk/client-cloudfront'
import { CloudFrontClient, ListOriginAccessControlsCommand } from '@aws-sdk/client-cloudfront'
import { Route53Client } from '@aws-sdk/client-route-53'
import { S3Provider } from '../../s3'
import { v4 as uuid } from 'uuid'
Expand Down Expand Up @@ -84,12 +84,28 @@ describe('PipelineSetupWorkflow', () => {
const pipelineId = uuid()
const developerId = uuid()

mockCloudFrontClient.send.mockImplementationOnce(() => ({
Distribution: {
DomainName: 'domain',
Id: 'id',
},
}))
mockCloudFrontClient.send.mockImplementation((event) => {
console.log('event', event)
if (event instanceof ListOriginAccessControlsCommand) {
return {
OriginAccessControlList: {
Items: [
{
Name: 'distro-to-s3',
Id: 'AOCID',
},
],
},
}
}

return {
Distribution: {
DomainName: 'domain',
Id: 'id',
},
}
})

mockRoute53Client.send.mockImplementationOnce(() => ({
ChangeInfo: {
Expand Down
Loading

0 comments on commit 08d1d81

Please sign in to comment.