import { Construct } from 'constructs'; import kebabCase from 'lodash.kebabcase'; import { S3Bucket, S3BucketObject } from '../generated/providers/aws/s3'; import { getId } from '../utils'; export type EnvFileEntries = [string, string][]; const getEnvVarFileContentsFromEntries = (entries: EnvFileEntries) => { return entries.map(([key, value]) => `${key}=${value}`).join('\n'); }; /** * A bucket specifically for env variables for this service */ export default class EnvVarsBucket extends Construct { readonly bucketName: string; readonly arn: string; constructor(scope: Construct, id: string) { super(scope, id); const bucket = new S3Bucket(this, 'bucket', { bucket: kebabCase(getId('api', 'env')), acl: 'private', versioning: { enabled: true, }, // @TODO: enable logging }); this.bucketName = bucket.bucket; this.arn = bucket.arn; } private getFileKey(fileName: string): string { return `${fileName}.env`; } /** * Adds an .env file to this bucket * NOTE: Do not include .env ending in `fileName` * @returns {string} the resource arn */ addEnvFile(fileName: string, entries: EnvFileEntries): string { const bucketObject = new S3BucketObject(this, fileName, { bucket: this.bucketName, key: this.getFileKey(fileName), content: getEnvVarFileContentsFromEntries(entries), }); return `${this.arn}/${bucketObject.key}`; } /** * Create an env file but does not change it's contents, allowing someone * else (human or otherwise) to write to this env file. */ ensureEnvFileExists(fileName: string): string { const bucketObject = new S3BucketObject(this, fileName, { bucket: this.bucketName, key: this.getFileKey(fileName), lifecycle: { ignoreChanges: ['content'], }, }); return `${this.arn}/${bucketObject.key}`; } }