Pulumi has many resource providers that allow you to interact with your favorite cloud or resource. There are times when a provider may not deliver on the specific task that you want to accomplish. Dynamic Providers can be a powerful tool to help accomplish your infrastructure tasks.
A provider manages the CRUD (Create, Read, Update, Delete) life-cycle of a resource against some underlying service. The underlying service can be one of the public clouds or an on-premise service. For example, AWS, Azure, GCP, and Kubernetes have resource providers, which can manage resources by request.
1. A resource plugin, which is the binary used by the deployment engine to manage a resource. These plugins are stored in the plugin cache (located in `~/.pulumi/plugins`) and can be managed using the [`pulumi plugin`](https://www.pulumi.com/docs/cli/commands/pulumi_plugin/) set of commands.
A resource provider is an extension of the API exposed by the respective cloud providers. As such, it can be the limiting factor. Thankfully, there is a solution to this. Since the Pulumi engine works with life-cycle callbacks handing control to the provider at appropriate times, it is easy to write a provider that implements custom logic in those callbacks.
Pulumi provides appropriate life-cycle callbacks through the `pulumi.dynamic.ResourceProvider` abstract class. While Pulumi does not know what sort of resources a Dynamic Provider will create, the life-cycle hooks must return data in specific formats, which Pulumi uses to call the appropriate callbacks.
For example, if the user changes an input property to your dynamic resource, the `diff` hook will be called with both the old (if applicable) and new inputs. You can compare then to see which input properties have changed and give hints to Pulumi as to whether `delete` should be called or whether to call the `update` hook.
When a dynamic resource instance updates, the `delete` hook will be called to allow you to perform any necessary cleanups before the dynamic resource is removed from your stack’s state.
If you need to use the credentials used by the rest of your Pulumi app, also known as the ambient provider credentials, you can access the relevant credentials (and other configuration) through the `<provider>.config` where `provider` is the imported provider module.
Dynamic providers can be used for almost any task. Since Pulumi uses general-purpose programming languages, you can do almost anything you would outside of your infrastructure app. You can even use libraries that are standard to the respective programming language.
The Azure resource provider does not support enabling the [static website](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website) feature for a storage account. However, there is a REST API that can be called to enable the feature, so we can easily call the API from within the dynamic provider.
[Here's](https://github.com/pulumi/examples/blob/5bcf9de17a660f17172ca05d4ca3f061456a99c5/azure-ts-static-website/staticWebsite.ts) the source for this example. The following is an excerpt from the [example](https://github.com/pulumi/examples/blob/e990699e03ff31af95bd62b08f31f8fb99b11ccb/azure-ts-static-website/index.ts) where the dynamic provider is actually used. Note that the Azure Storage Account is created before using this dynamic provider.
Similar to the previous example, this is another example of a shortcoming of the regular Azure resource provider available in Pulumi. However, due to the availability of a REST API, we can easily add a custom domain to an Azure CDN resource using a dynamic provider.
Along with adding a custom domain to the CDN endpoint, this dynamic provider also enables HTTPS provided by Azure's one-click [HTTPS enablement](https://docs.microsoft.com/en-us/azure/cdn/cdn-custom-ssl?tabs=option-1-default-enable-https-with-a-cdn-managed-certificate).
As before, details such as the creation of the CDN profile and its endpoint are omitted for clarity. You can check out the full example [here](https://github.com/pulumi/examples/tree/master/classic-azure-ts-dynamicresource).
Provisioning a VM after it is created is a common problem. Developers have the option to run user-supplied scripts while creating the VM itself. For example, the AWS EC2 resource has a `userData` parameter, that allows you to specify an inline script, which EC2 will run at instance startup.
Scripts provided through the `userData` parameter can be configured to run every time the instance is restarted. But what if you wanted to run the script every time the _script_ changes? To do that you could use SCP to transfer the file and then execute the script on the VM. This [example](https://github.com/pulumi/examples/tree/master/aws-ts-ec2-provisioners) shows you how you can do that. Although the example uses TypeScript and is specific to AWS EC2, you can easily adapt this to other cloud providers.
Read more about dynamic providers in our [docs](/docs/concepts/resources/dynamic-providers/). Let us know what cool dynamic providers you create by dropping us a note on our community [Slack](https://slack.pulumi.com/)!