pulumi / pulumi-aws

An Amazon Web Services (AWS) Pulumi resource package, providing multi-language access to AWS
Apache License 2.0
464 stars 155 forks source link

Invalidating Cloudfront cache for static hosting on S3. #916

Closed seivan closed 2 years ago

seivan commented 4 years ago

Is there anyway to bust caches on Cloudfront for the index.html for new deployments? Looking at the docs there is a way to track current cache invalidation in progress, but no way to deploy a new invalidation after an update.

Open to other suggestions, like setting no cache as settings for index.html on either S3 or Cloudfront, but I rather not and prefer to do explicit cache busting on new deploys.

leezen commented 4 years ago

That's correct. One thing you could do is simply mix in the AWS SDK code directly and create an invalidation. If you want to integrate it such that it only runs when the underlying S3 object changes, you could look into doing this via dynamic providers: https://www.pulumi.com/docs/intro/concepts/programming-model/#dynamicproviders

seivan commented 4 years ago

That sound like a pretty decent solution, thanks! Is it possible to run the AWS SDK as part of the pulumi runtime? Since I’d need access to a few runtime values and it would be a hassle to extract them out. Also curious how it would work with pulumis lazy nature?

leezen commented 4 years ago

Yes, there's nothing preventing you from mixing the two SDKs together. In terms of working with the 'lazy' nature of Pulumi, you'll typically want to do anything w/ the SDK via .promise() on the calls (instead of callbacks), then using those promises as any other promise (similar to doing a resource .get() with { async: true } in the InvokeOptions). This works nicely with the fact that Input<T> types take T Output<T> as well as Promise<T>

leezen commented 2 years ago

Probably a cleaner way to model this now is to use the Command provider and run a local command to invalidate the object.

For example, something along these lines:


indexFile = new aws.s3.BucketObject("index", { ... });
invalidationCommand = new command.local.Command("invalidate", {
  create: pulumi.interpolate`aws cloudfront create-invalidation --distribution-id ${distribution.id} --paths index.html`
  environment: {
    ETAG: indexFile.etag
  }
}, {
    replaceOnChanges: ["environment"]
});
H0R5E commented 1 year ago

If anyone else comes here, I would recommend using the triggers argument to command.local.Command rather than replaceOnChanges.

I went down a deep rabbit hole trying to get replaceOnChanges to work for a file hash (which I even converted to a dynamic resource) but with no joy.