From 554b8f5d08401b5340917abbb43bdf080b1b026e Mon Sep 17 00:00:00 2001 From: Vahor Date: Tue, 26 Dec 2023 11:24:06 +0100 Subject: [PATCH] feat: add encrypted bucket --- aws/policies/pulumi.json | 1 + src/aws/constants.ts | 4 ++ src/aws/index.ts | 2 + src/aws/resources/encrypted-bucket.ts | 81 +++++++++++++++++++++++++++ src/aws/resources/files-bucket.ts | 22 +------- src/aws/resources/rds-group.ts | 2 + src/aws/resources/static-bucket.ts | 3 + src/aws/secrets/parameters.ts | 2 + src/aws/users/api-pulumi.ts | 4 ++ 9 files changed, 101 insertions(+), 20 deletions(-) create mode 100644 src/aws/constants.ts create mode 100644 src/aws/resources/encrypted-bucket.ts diff --git a/aws/policies/pulumi.json b/aws/policies/pulumi.json index 7cde51a..b70f212 100644 --- a/aws/policies/pulumi.json +++ b/aws/policies/pulumi.json @@ -15,6 +15,7 @@ ], "Resource": [ "arn:aws:s3:::files.pedaki.fr", + "arn:aws:s3:::encrypted.pedaki.fr", "arn:aws:s3:::static.pedaki.fr" ] }, diff --git a/src/aws/constants.ts b/src/aws/constants.ts new file mode 100644 index 0000000..3ca12e0 --- /dev/null +++ b/src/aws/constants.ts @@ -0,0 +1,4 @@ +export const TAGS = { + team: 'pedaki', + repository: 'infrastructure', +}; diff --git a/src/aws/index.ts b/src/aws/index.ts index fe7df94..0f5c26b 100644 --- a/src/aws/index.ts +++ b/src/aws/index.ts @@ -1,3 +1,4 @@ +import { createEncryptedBucket } from './resources/encrypted-bucket'; import { createFilesBucket } from './resources/files-bucket'; import { createRdsParameterGroup } from './resources/rds-group'; import { createStaticBucket } from './resources/static-bucket'; @@ -5,6 +6,7 @@ import { createSharedParameters } from './secrets/parameters'; import { createApiPulumiUser } from './users/api-pulumi'; createFilesBucket(); +createEncryptedBucket(); createStaticBucket(); createApiPulumiUser(); createSharedParameters(); diff --git a/src/aws/resources/encrypted-bucket.ts b/src/aws/resources/encrypted-bucket.ts new file mode 100644 index 0000000..063fc60 --- /dev/null +++ b/src/aws/resources/encrypted-bucket.ts @@ -0,0 +1,81 @@ +import * as aws from '@pulumi/aws'; +import * as cloudflare from '@pulumi/cloudflare'; +import { env } from '../../env'; +import { TAGS } from '../constants'; + +export const createEncryptedBucket = () => { + const bucket = new aws.s3.Bucket('encrypted.pedaki.fr', { + bucket: 'encrypted.pedaki.fr', + acl: 'private', + serverSideEncryptionConfiguration: { + rule: { + applyServerSideEncryptionByDefault: { + sseAlgorithm: 'aws:kms', + }, + bucketKeyEnabled: true, + }, + }, + tags: TAGS, + }); + + const publicAccessBlock = new aws.s3.BucketPublicAccessBlock( + 'encrypted.pedaki.fr-publicAccessBlock', + { + bucket: bucket.id, + blockPublicAcls: true, + ignorePublicAcls: true, + blockPublicPolicy: true, + restrictPublicBuckets: true, + }, + ); + + const policy = new aws.s3.BucketPolicy( + 'encrypted-bucket-policy', + { + bucket: bucket.id, + policy: bucket.arn.apply(arn => + JSON.stringify({ + // all files should be encrypted + Version: '2012-10-17', + Statement: [ + { + Sid: 'DenyUnEncryptedObjectUploads', + Effect: 'Deny', + Principal: '*', + Action: 's3:PutObject', + Resource: `${arn}/*`, + Condition: { + StringNotEquals: { + 's3:x-amz-server-side-encryption': 'aws:kms', + }, + }, + }, + { + Sid: 'DenyUnEncryptedObjectDownloads', + Effect: 'Deny', + Principal: '*', + Action: 's3:GetObject', + Resource: `${arn}/*`, + Condition: { + Bool: { + 'aws:SecureTransport': 'false', + }, + }, + }, + ], + }), + ), + }, + { dependsOn: [publicAccessBlock] }, + ); + + const record = new cloudflare.Record('encrypted.pedaki.fr', { + name: 'files', + type: 'CNAME', + value: bucket.bucketDomainName, + zoneId: env.CLOUDFLARE_ZONE_ID, + proxied: true, + ttl: 1, // TTL must be set to 1 when proxied is true + comment: `pulumi (infrastructure repo)`, + }); +}; diff --git a/src/aws/resources/files-bucket.ts b/src/aws/resources/files-bucket.ts index 4387e17..8eee7ad 100644 --- a/src/aws/resources/files-bucket.ts +++ b/src/aws/resources/files-bucket.ts @@ -1,19 +1,13 @@ import * as aws from '@pulumi/aws'; import * as cloudflare from '@pulumi/cloudflare'; import { env } from '../../env'; +import { TAGS } from '../constants'; export const createFilesBucket = () => { const bucket = new aws.s3.Bucket('files.pedaki.fr', { bucket: 'files.pedaki.fr', acl: 'private', - serverSideEncryptionConfiguration: { - rule: { - applyServerSideEncryptionByDefault: { - sseAlgorithm: 'aws:kms', - }, - bucketKeyEnabled: true, - }, - }, + tags: TAGS, }); const publicAccessBlock = new aws.s3.BucketPublicAccessBlock( @@ -36,18 +30,6 @@ export const createFilesBucket = () => { // all files should be encrypted Version: '2012-10-17', Statement: [ - { - Sid: 'DenyUnEncryptedObjectUploads', - Effect: 'Deny', - Principal: '*', - Action: 's3:PutObject', - Resource: `${arn}/*`, - Condition: { - StringNotEquals: { - 's3:x-amz-server-side-encryption': 'aws:kms', - }, - }, - }, { Sid: 'AllowPublicReadAccess', Effect: 'Allow', diff --git a/src/aws/resources/rds-group.ts b/src/aws/resources/rds-group.ts index c2fee59..8990e49 100644 --- a/src/aws/resources/rds-group.ts +++ b/src/aws/resources/rds-group.ts @@ -1,4 +1,5 @@ import * as aws from '@pulumi/aws'; +import { TAGS } from '../constants'; export const createRdsParameterGroup = () => { const group = new aws.rds.ParameterGroup('rds-pedaki', { @@ -6,5 +7,6 @@ export const createRdsParameterGroup = () => { description: 'Shared parameter group', name: 'rds-pedaki', parameters: [{ name: 'require_secure_transport', value: '1' }], + tags: TAGS, }); }; diff --git a/src/aws/resources/static-bucket.ts b/src/aws/resources/static-bucket.ts index 7f5f70f..95c3318 100644 --- a/src/aws/resources/static-bucket.ts +++ b/src/aws/resources/static-bucket.ts @@ -1,10 +1,13 @@ import * as aws from '@pulumi/aws'; import * as cloudflare from '@pulumi/cloudflare'; import { env } from '../../env'; +import { TAGS } from '../constants'; export const createStaticBucket = () => { const bucket = new aws.s3.Bucket('static.pedaki.fr', { bucket: 'static.pedaki.fr', + acl: 'public-read', + tags: TAGS, }); const publicAccessBlock = new aws.s3.BucketPublicAccessBlock( diff --git a/src/aws/secrets/parameters.ts b/src/aws/secrets/parameters.ts index 8494c4b..6cbf0bc 100644 --- a/src/aws/secrets/parameters.ts +++ b/src/aws/secrets/parameters.ts @@ -1,5 +1,6 @@ import * as aws from '@pulumi/aws'; import { env } from '../../env'; +import { TAGS } from '../constants'; export const createSharedParameters = () => { createSecret( @@ -67,6 +68,7 @@ function createSecret(name: string, description: string, value: string) { description, type: 'SecureString', value: value, + tags: TAGS, }); return secret.name; diff --git a/src/aws/users/api-pulumi.ts b/src/aws/users/api-pulumi.ts index d4d32a9..6805276 100644 --- a/src/aws/users/api-pulumi.ts +++ b/src/aws/users/api-pulumi.ts @@ -1,9 +1,11 @@ import * as aws from '@pulumi/aws'; +import { TAGS } from '../constants'; export const createApiPulumiUser = () => { // IAM user that will be responsible to create the ec2, rds, etc. for the whole stack const user = new aws.iam.User('api-pulumi', { name: 'api-pulumi', + tags: TAGS, }); const _ = new aws.iam.UserPolicy('api-pulumi-policy', { @@ -69,6 +71,8 @@ export const createApiPulumiUser = () => { 'arn:aws:s3:::files.pedaki.fr/*', 'arn:aws:s3:::static.pedaki.fr', 'arn:aws:s3:::static.pedaki.fr/*', + 'arn:aws:s3:::encrypted.pedaki.fr', + 'arn:aws:s3:::encrypted.pedaki.fr/*', ], }, ],