s3Helpers.ts 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import * as fs from 'fs'
  2. import * as mime from 'mime'
  3. import * as aws from '@pulumi/aws'
  4. import * as pulumi from '@pulumi/pulumi'
  5. interface FileObject {
  6. name: string
  7. path: string
  8. }
  9. export interface FileBucketOpts {
  10. files: FileObject[]
  11. policy?: (bucket: aws.s3.Bucket) => pulumi.Output<string>
  12. }
  13. export class FileBucket {
  14. public readonly bucket: aws.s3.Bucket
  15. public readonly files: { [key: string]: aws.s3.BucketObject }
  16. public readonly policy: aws.s3.BucketPolicy | undefined
  17. private readonly fileContents: { [key: string]: string }
  18. constructor(bucketName: string, opts: FileBucketOpts) {
  19. this.bucket = new aws.s3.Bucket(bucketName)
  20. this.fileContents = {}
  21. this.files = {}
  22. for (const file of opts.files) {
  23. this.fileContents[file.name] = fs.readFileSync(file.path).toString()
  24. this.files[file.name] = new aws.s3.BucketObject(file.name, {
  25. bucket: this.bucket,
  26. source: new pulumi.asset.FileAsset(file.path),
  27. contentType: mime.getType(file.path) || undefined,
  28. })
  29. }
  30. if (opts.policy !== undefined) {
  31. // Set the access policy for the bucket so all objects are readable
  32. this.policy = new aws.s3.BucketPolicy(`bucketPolicy`, {
  33. bucket: this.bucket.bucket,
  34. // policy: this.bucket.bucket.apply(publicReadPolicyForBucket)
  35. policy: opts.policy(this.bucket),
  36. })
  37. }
  38. }
  39. getUrlForFile(file: string): pulumi.Output<string> {
  40. if (!(file in this.files)) {
  41. throw new Error(`Bucket does not have file '${file}'`)
  42. }
  43. return pulumi.all([this.bucket.bucketDomainName, this.files[file].id]).apply(([domain, id]) => `${domain}/${id}`)
  44. }
  45. }
  46. // Create an S3 Bucket Policy to allow public read of all objects in bucket
  47. export function publicReadPolicy(bucket: aws.s3.Bucket): pulumi.Output<string> {
  48. return bucket.bucket.apply((bucketName) =>
  49. JSON.stringify({
  50. Version: '2012-10-17',
  51. Statement: [
  52. {
  53. Effect: 'Allow',
  54. Principal: '*',
  55. Action: ['s3:GetObject'],
  56. Resource: [
  57. `arn:aws:s3:::${bucketName}/*`, // policy refers to bucket name explicitly
  58. ],
  59. },
  60. ],
  61. })
  62. )
  63. }