diff --git a/content/docs/pulumi-cloud/deployments/faq.md b/content/docs/pulumi-cloud/deployments/faq.md index 75798c73b3d4..a1d636afaf84 100644 --- a/content/docs/pulumi-cloud/deployments/faq.md +++ b/content/docs/pulumi-cloud/deployments/faq.md @@ -30,25 +30,6 @@ Deployments will remain in the queue for a maximum of 7 days. If a deployment is It is possible to pause deployments at the stack or organization level. Deployments that are already running are allowed to complete and are not paused. New deployments are queued, and will run when the stack or organization’s deployments are resumed. -## Dependency caching - -When using Pulumi-managed deployment agents, you have the option to speed up deployments using *dependency caching*. - -The caching method is simple: during the first deployment, the deployment agent will automatically detect downloaded dependencies using lock files, zip them up and store the archive in blob storage. During all subsequent deployments, agents will pull such an archive down and unpack it, saving time it would normally take to download those dependencies. When your dependencies change, deployment agents will automatically invalidate the old cache and create a new one. - -Caches are shared on the project level, so all stacks within a project can share the same cache. However, caches are fully isolated and never shared between customers. - -Dependency caching is supported for the following runtimes: - -- `.NET` - no special configuration required -- `Python` - ensure that you have `requirements.txt` in the root of your source code. -- `Go` - ensure that you have `go.mod` and `go.sum` in the root of your source code. -- `NodeJS` - ensure that you have `packageManager` field specified in `package.json`. For now, only `npm` and `yarn` are supported. - - For `npm`, ensure that you have `package-lock.json` in the root of your source code. - - For `yarn`, ensure that you have `yarn.lock` in the root of your source code. - -To confirm dependency caching is working and/or to troubleshoot, check out logs of your deployments, specifically the `Restore Cache` and `Save Cache` steps. - ## Common recipes See [Using Deployments](/docs/pulumi-cloud/deployments/reference/) for common recipes and best practices. diff --git a/content/docs/pulumi-cloud/deployments/permissions.md b/content/docs/pulumi-cloud/deployments/permissions.md new file mode 100644 index 000000000000..e664dca50752 --- /dev/null +++ b/content/docs/pulumi-cloud/deployments/permissions.md @@ -0,0 +1,71 @@ +--- +title_tag: "Deployment Permissions | Pulumi Deployments" +meta_desc: Learn how to configure and manage permissions for Pulumi Deployments +title: "Deployment Permissions" +h1: "Deployment Permissions" +meta_image: /images/docs/meta-images/docs-meta.png +menu: + cloud: + parent: pulumi-cloud-deployments + weight: 8 +--- + +This page explains how permissions work in Pulumi Deployments and how to configure them for your deployment needs. + +## Default Deployment Permissions + +By default, the permissions that are granted to a deployment depend on how the deployment is being invoked: + +- If the deployment is created via the **REST API** or by using the **Actions buttons** in the Pulumi Cloud console, it is granted the permissions of the user that has executed the action. +- If a deployment is created because of a **`git push`** or a **pull request**, it uses an ephemeral stack token that has admin permissions on only the stack itself, but nothing else. + +## Permissions Impact + +The permission model has the following practical implications: + +- If your organization has default stack permissions set to `NONE`, then any deployment created by a `git push` or a pull request will not be able to access any [Stack References](https://www.pulumi.com/docs/concepts/stack/#stackreferences), and will fail if it tries to do so. + +- If your organization has default environment permissions set to `NONE`, then any deployment created by a `git push` or a pull request will not be able to access any [ESC Environments](https://www.pulumi.com/docs/esc/environments/) that are listed in the stack's configuration file. + +## Granting Additional Permissions + +If you want to change the permissions that are granted to a deployment, you can do so by setting the `PULUMI_ACCESS_TOKEN` environment variable to a token with the desired permissions in the stack's deployment settings. + +This token can be an individual, team, or organization token, and it will grant the deployment the permissions that are associated with the token. If this environment variable is set, it will be used regardless of how the deployment was created (REST API, `git push`, etc.). + +### Minimum Required Token Permissions + +If using an individual or team token, the token must have at minimum: + +- `WRITE` access to the stack that is being deployed +- `READ` access to any stacks from which Stack References are being used +- `OPEN` access to any ESC environment that is listed in the stack's configuration file, including any environments that are imported transitively + +## Using ESC with Deployments + +For enhanced security and simplified credential management, we recommend configuring your stack to use [Pulumi ESC](/docs/esc/) for cloud credentials and ensuring the Deployment has an appropriately scoped Pulumi token. + +This approach offers several advantages: + +- Dynamic, short-lived credentials instead of long-lived static credentials +- Fine-grained control over credential scope and permissions +- Centralized credential management +- Reduced risk of credential exposure +- Complete audit trail of credential usage + +### Configuring ESC for Deployments + +1. Create an ESC environment with the appropriate cloud provider credentials +2. Reference this environment in your Pulumi stack configuration +3. Create a Pulumi access token with the appropriate permissions (as described above) +4. Add this token as the `PULUMI_ACCESS_TOKEN` environment variable in your deployment settings + +For more information on setting up ESC environments, see the [ESC documentation](/docs/esc/). + +You can use ESC with pre-run commands in Deployments by prefixing each command with `pulumi env run`. For example: + +```bash +pulumi env run my-aws-env -- aws s3 ls +``` + +This executes the `aws s3 ls` command with credentials from your `my-aws-env` ESC environment. diff --git a/content/docs/pulumi-cloud/deployments/reference.md b/content/docs/pulumi-cloud/deployments/reference.md deleted file mode 100644 index b3832bd2ea07..000000000000 --- a/content/docs/pulumi-cloud/deployments/reference.md +++ /dev/null @@ -1,896 +0,0 @@ ---- -title_tag: "Using Pulumi Deployments" -meta_desc: Reference documentation for configuring and using Pulumi Deployments -title: "Using Deployments" -h1: "Using Pulumi Deployments" -meta_image: /images/docs/meta-images/docs-meta.png -menu: - cloud: - name: Using Deployments - parent: pulumi-cloud-deployments - weight: 2 - identifier: pulumi-cloud-deployments-reference -aliases: - - /docs/intro/deployments/reference/ ---- - -This page highlights some common patterns and workflows using Pulumi Deployments. - -## Deployment Settings - -Deployment settings refer to the full set of configuration required to run a Pulumi Deployment, defined on a per-stack basis. These settings may be defined once for the stack, via the UI, Pulumi Service provider, or the REST API and can be consumed using any of the triggers, i.e., push-to-deploy, click-to-deploy, or via the REST API. - -### From the Pulumi Cloud UI - -From the Pulumi Console, a stack's deployment settings can be accessed via the `Settings > Deploy` tab. Once the settings are defined via the UI, they apply to all Deployment triggers, including push-to-deploy (if you have the GitHub app installed), click-to-deploy and the REST API. - -![Pulumi UI - Deployment Settings](../ui-settings.png) - -### From the API - -Alternatively, a stack's deployment settings may be defined and subsequently modified using the REST API. - -```POST https://api.pulumi.com/{org}/{project}/{stack}/deployment/settings``` - -```json -{ - "sourceContext": { - "git": { - "repoURL": "https://github.com/pulumi/deploy-demos.git", - "branch": "main", - "repoDir": "pulumi-programs/simple-resource" - } - }, - "operationContext": { - "environmentVariables": { - "TEST_VAR": "foo", - "SECRET_VAR": { - "secret": "my-secret" - } - } - } -} -``` - -To modify an environment variable in the deployment settings, you only need to specify the changed settings: - -```POST https://api.pulumi.com/api/stacks/{org}/{project}/{stack}/deployments/settings``` - -```json -{ - "operationContext": { - "environmentVariables": { - "TEST_VAR": "new_value" - } - } -} -``` - -The [REST API documentation](../api) contains much more thorough information about individual API properties. - -### Defined as Code with the Pulumi Cloud Service provider - -Finally, a stack's deployment settings may be defined as a resource within the stack itself using the Pulumi Service provider. This lets you securely store your settings in source control alongside your code. - -We recommend that a stack does not configure it's own Deployment Settings, as this would require two deployments for settings changes to take effect. Typically, users create a stack per cloud environment that defines Deployment Settings for all other stacks that deploy into that account or environment. This enables centralizing and sharing common configuration such as OIDC providers. Commonly, these stacks that manage Deployment Settings are themselves managed by Pulumi Deployments and benefit from the pull request and code review workflow. - -```typescript -import * as pulumi from "@pulumi/pulumi"; -import * as service from "@pulumi/pulumiservice"; - -const config = new pulumi.Config(); - -const settings = new service.DeploymentSettings("deployment_settings", { - organization: "service-provider-test-org", - project: "test-deployment-settings-project", - stack: "dev", - operationContext: { - environmentVariables: { - TEST_VAR: "foo", - SECRET_VAR: config.requireSecret("my_secret"), - } - }, - sourceContext: { - git: { - repoUrl: "https://github.com/pulumi/deploy-demos.git", - branch: "refs/heads/main", - repoDir: "pulumi-programs/simple-resource" - } - } -}); -``` - -## Deployment Triggers - -A deployment trigger refers to a method of initializing a deployment. Currently, a deployment may be triggered using the REST API, by clicking a button in the Pulumi Console, via a Review Stack, or via a `git push` if the GitHub application is installed. - -### REST API - -Once deployment settings are defined for a stack, triggering a deployment is as simple as a one-line request. - -```POST https://api.pulumi.com/api/stacks/{org}/{project}/{stack}/deployments``` - -```json -{ - "operation": "update/preview/refresh/destroy" -} -``` - -If you need to override some specific settings, you can specify them in the request body. - -```POST https://api.pulumi.com/api/stacks/{org}/{project}/{stack}/deployments``` - -```json -{ - "operation": "update/preview/refresh/destroy", - "operationContext": { - "environmentVariables": { - "EXTRA_VAR": { - "secret": "my-super-secret-value" - } - } - } -} -``` - -If you would rather not use the predefined settings at all, you must set `inheritSettings` to `false` in your request body and define the entire settings object. - -The merge behavior of deployment settings are further explained in the [REST API documentation](../api). - -### Click to Deploy - -A deployment may be triggered at the simple click of a button in the Pulumi Console. Useful to test if your deployment settings are configured correctly or to execute one-off deployments. - -![Pulumi UI - Click to Deploy](../ui-deploy-button.png) - -### GitHub Push to Deploy - -Once you have the GitHub application installed in your Pulumi organization, you can choose to have deployments run a `pulumi preview` when Pull Requests are opened against a target branch, or `pulumi up` when a commit is pushed to a branch. - -{{% notes type="info" %}} - -The `pulumi preview` on Pull Request capability requires that the Github user creating the Pull Request has their Github Organization Visibility set to `Public`. - -{{% /notes %}} - -![Pulumi UI - Push to Deploy](../ui-push-to-deploy.png) - -### Review Stacks - -[Review Stacks](/docs/pulumi-cloud/deployments/review-stacks) are dedicated cloud environments that get created automatically every time a pull request is opened, all powered by Pulumi Deployments. Open a pull request, and Pulumi Deployments will stand up a stack with your changes and the Pulumi GitHub App will add a PR comment with the outputs from your deployment. Merge the PR and Pulumi Deployments will destroy the stack and free up the associated resources. - -![Review Stack Pull Request Comment](../comment.png) - -## Configuring push-to-deploy from GitHub - -### GitHub App Installation - -To use push-to-deploy functionality, you'll need to install and configure the [Pulumi GitHub App](/docs/iac/using-pulumi/continuous-delivery/github-app/#installation-and-configuration). The app requires read access to your repos so it can clone your Pulumi programs and listen to merge commits to automatically trigger deployments on `git push`. - -The complete installation instructions are available in the [GitHub App documentation](/docs/iac/using-pulumi/continuous-delivery/github-app/#installation-and-configuration). - -### Configuring settings - -Once the GitHub app has been installed, the deployment settings for a stack can be defined using the methods defined in the `Deployment Settings` section. - -## Common Scenarios - -### Environment variables - -By default, there are a set of environment variables set by the process automatically: - -- `GITHUB_TOKEN`: Personal Access Token configured when the source is GitHub (unless there is a token configured by the custom environment variables) -- `PULUMI_ACCESS_TOKEN`: A temporary token with read-write access only to the stack being deployed. -- `PULUMI_DEPLOY_OIDC_CONFIG`: OIDC configuration provided for the cloud integrations -- `PULUMI_CI_SYSTEM`: "Pulumi Deployments" -- `PULUMI_CI_BUILD_ID`: Current deployment ID -- `PULUMI_CI_BUILD_NUMBER`: Current deployment version -- `PULUMI_CI_BUILD_URL`: Current deployment URL -- `PULUMI_CI_ORGANIZATION`: Current account organization -- `PULUMI_CI_PROJECT`: Current project name -- `PULUMI_CI_STACK`: Current stack name - -These can be overridden or extended by configuring custom environment variables: - -![Pulumi UI - Environment Variables](../ui-custom-env-variables.png) - -#### PULUMI_ENV - -Environment variables can be persisted between pre-run commands and the final pulumi deployment by appending them to the file on the file system named `PULUMI_ENV`. - -Example Usage: - -```bash -export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) -echo GOOGLE_OAUTH_ACCESS_TOKEN=$GOOGLE_OAUTH_ACCESS_TOKEN >> /PULUMI_ENV -``` - -Running `env` in a subsequent pre-run command will show the environment variable and it should be usable by scripts or your pulumi program. -{{% notes type="info" %}} -If `/PULUMI_ENV` does not work, and you are on self hosted, you can look for the following message in the logs to get the location: `Loading PULUMI_ENV from`. -{{% /notes %}} - -### Deployment permissions - -By default, the permissions that are granted to a deployment depend on how the deployment is being invoked. If the -deployment is created via the REST API or by using the Actions buttons in the Pulumi Cloud console, it is -granted the permissions of the user that has executed the action. However, if a deployment is created because of a `git push` -or a pull request, it uses an ephemeral stack token that has admin permissions on only the stack itself, but nothing -else. - -In practice, the consequences of this are twofold: - -- If your organization has default stack permissions set to `NONE`, then any deployment created by a `git push` or a pull - request will not be able to access any [Stack References](https://www.pulumi.com/docs/concepts/stack/#stackreferences), - and will fail if it tries to do so. -- If your organization has default environment permissions set to `NONE`, then any deployment created by a `git push` or a - pull request will not be able to access any [ESC Environments](https://www.pulumi.com/docs/esc/environments/) that are - listed in the stack's configuration file. - -#### Granting extra permissions to a deployment - -If you want to change the permissions that are granted to a deployment, you can do so by setting the `PULUMI_ACCESS_TOKEN` -environment variable to a token with the desired permissions in the stack's deployment settings. This token can be an individual, -team or organization token, and it will grant the deployment the permissions that are associated with the token. If this -environment variable is set it will be used regardless of how the deployment was created (REST API, `git push`, etc.). - -If using an individual or team token, the token must have at minimum: - -- `WRITE` access to the stack that is being deployed -- `READ` access to any stacks from which Stack References are being used -- `OPEN` access to any ESC environment that is listed in the stack's configuration file, including any environments that are imported transitively. - -### Path filtering - -When using the GitHub app and push-to-deploy, you may want to filter deployment events to only target file changes in specific directories. You can easily do this using path filtering, so a deployment is only triggered if there is a change in files that match the path filters. This is especially useful for monorepos where you may have multiple Pulumi programs within the same repository. - -Path filters are relative to the repository root, and should reference a file by name or a directory must reference files by name relative to the repository or directories via glob patterns such as `/**` to include all changes within a directory. - -![Pulumi UI - Path Filters](../ui-path-filters.png) - -As with any other deployment setting, the path filters may be set via the Pulumi Console, using the REST API or defined in code using the Service provider. - -### Private dependency packages - -If your Pulumi Deployment requires access to private GitHub repositories, e.g. your program uses a private Go module, it is necessary to configure an SSH key with access to the required repos. Without the correct configuration, the Deployment will be unable to access those private artifacts, and the deployment may fail. - -The following will allow you to configure a private key and allow access to GitHub using SSH to pull down the appropriate artifacts properly: - -1. Add the following code into the `Pre-run commands` and toggle on `Skip automatic dependency installation step` in Advanced Settings: - - ```bash - mkdir /root/.ssh && printf -- "$SSHKEY" > /root/.ssh/id_ed25519 - chmod 600 /root/.ssh/id_ed25519 - ssh-keyscan github.com >> ~/.ssh/known_hosts - cd .. && git config --global --add url.\"git@github.com:\".insteadOf \"https://github.com\" - ``` - - ![SSH Key Prerun Command](../limit-prerun-cmd.png) - -2. Add the `$SSHKEY` field as a secret environment variable: - -![SSH Key Env Variable](../limit-env.png) - -### Skip intermediate deployments - -By default, when multiple deployments are pushed, they will be executed sequentially until the backlog is completed. In some cases, you may wish to only execute the most recent deployment since the changes are accumulative. By enabling the `Skip intermediate deployments` setting, Pulumi will skip all intermediary deployments of the same type and will execute only the latest. - -![Pulumi UI - Skip intermediate deployments](../ui-skip-intermediate-deployments.png) - -### Customizing the deployment environment - -By default, the deployment is executed using the [pulumi/pulumi](https://hub.docker.com/r/pulumi/pulumi) image. -The pulumi/pulumi image is a unix-based image which includes the pulumi CLI in its `$PATH` and the [LTS versions](https://github.com/pulumi/pulumi-docker-containers/blob/main/README.md#version-policy) of all supported SDK runtime(s) for your Pulumi program. - -However, there may be scenarios where you might want to customize the image used for the execution, e.g. if you want to use a different version of python or need to include additional dependencies. - -This is possible by specifying a custom executor image for your deployment. Using the custom executor image field, you can pin to a specific version of the pulumi/pulumi image, -or point to a completely custom image hosted in a public or private container registry. - -![Pulumi UI - Custom Executor](../ui-custom-executor.png) - -Image requirements: - -- It must be a unix-based image which includes `curl`. -- It must include the `pulumi` CLI in its `$PATH`. -- It must include the required SDK runtime(s) for your Pulumi program. - -{{% notes "info" %}} - -Using a custom image may result in slower execution due to time spent pulling the image. - -{{% /notes %}} - -### Customizing the dependency installation step - -By default, the deployment executor will attempt to install dependencies for your project by using the default dependency manager for the language (i.e. `npm` for nodejs or `virtualenv` for python). However, there may be scenarios where you may want to have more control over the dependency installation step (e.g. you are using `yarn` and/or a different version of `node` than the one that is installed by default). - -This is enabled by skipping the default dependency installation step (under Advanced Settings in the UI), and setting a few pre-run commands and environment variables. - -![Pulumi UI - Node Version](../ui-node-version.png) - -### Deploying dependent stacks - -Pulumi Deployments can be used to automatically deploy dependent stacks via Deployment Webhooks. This enables you to keep your infrastructure up-to-date across stack reference boundaries. This can be configured in one of two ways: - -1. [Deployment Webhook Destinations](/docs/pulumi-cloud/webhooks/#deployment-webhooks) -2. [The Pulumi Auto Deploy Package](/registry/packages/auto-deploy) - -Either method requires that your stacks are configured with [Deployment Settings](/docs/pulumi-cloud/deployments/reference/#deployment-settings). - -#### Deployment webhook destinations - -[Deployment Webhook Destinations](/docs/pulumi-cloud/webhooks/#deployment-webhooks) allow you to pick one or more event types on a stack (i.e. `update succeeded`, or `refresh failed`) and automatically deliver an event to a destination - in this case the Create Deployment API for another Stack. - -{{< chooser language "typescript,python,go,csharp,yaml" >}} - -{{% choosable language typescript %}} - -```ts -import * as pulumi from "@pulumi/pulumi"; -import * as pulumiservice from "@pulumi/pulumiservice"; - -const databaseWebhook = new pulumiservice.Webhook("databaseWebhook", { - organizationName: "org", - projectName: "network", - stackName: "prod", - format: pulumiservice.WebhookFormat.PulumiDeployments, - payloadUrl: "database/prod", - active: true, - displayName: "deploy-database", - filters: [pulumiservice.WebhookFilters.UpdateSucceeded], -}); -const computeWebhook = new pulumiservice.Webhook("computeWebhook", { - organizationName: "org", - projectName: "database", - stackName: "prod", - format: pulumiservice.WebhookFormat.PulumiDeployments, - payloadUrl: "compute/prod", - active: true, - displayName: "deploy-compute", - filters: [pulumiservice.WebhookFilters.UpdateSucceeded], -}); -``` - -{{% /choosable %}} -{{% choosable language csharp %}} - -```csharp -using System.Collections.Generic; -using System.Linq; -using Pulumi; -using PulumiService = Pulumi.PulumiService; - -return await Deployment.RunAsync(() => -{ - var databaseWebhook = new PulumiService.Webhook("databaseWebhook", new() - { - OrganizationName = "org", - ProjectName = "network", - StackName = "prod", - Format = PulumiService.WebhookFormat.PulumiDeployments, - PayloadUrl = "database/prod", - Active = true, - DisplayName = "deploy-database", - Filters = new[] - { - PulumiService.WebhookFilters.UpdateSucceeded, - }, - }); - - var computeWebhook = new PulumiService.Webhook("computeWebhook", new() - { - OrganizationName = "org", - ProjectName = "database", - StackName = "prod", - Format = PulumiService.WebhookFormat.PulumiDeployments, - PayloadUrl = "compute/prod", - Active = true, - DisplayName = "deploy-compute", - Filters = new[] - { - PulumiService.WebhookFilters.UpdateSucceeded, - }, - }); - -}); -``` - -{{% /choosable %}} - -{{% choosable language python %}} - -```python -import pulumi -import pulumi_pulumiservice as pulumiservice - -database_webhook = pulumiservice.Webhook("databaseWebhook", - organization_name="org", - project_name="network", - stack_name="prod", - format=pulumiservice.WebhookFormat.PULUMI_DEPLOYMENTS, - payload_url="database/prod", - active=True, - display_name="deploy-database", - filters=[pulumiservice.WebhookFilters.UPDATE_SUCCEEDED]) -compute_webhook = pulumiservice.Webhook("computeWebhook", - organization_name="org", - project_name="database", - stack_name="prod", - format=pulumiservice.WebhookFormat.PULUMI_DEPLOYMENTS, - payload_url="compute/prod", - active=True, - display_name="deploy-compute", - filters=[pulumiservice.WebhookFilters.UPDATE_SUCCEEDED]) -``` - -{{% /choosable %}} - -{{% choosable language go %}} - -```go -package main - -import ( - "github.com/pulumi/pulumi-pulumiservice/sdk/go/pulumiservice" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi" -) - -func main() { - pulumi.Run(func(ctx *pulumi.Context) error { - _, err := pulumiservice.NewWebhook(ctx, "databaseWebhook", &pulumiservice.WebhookArgs{ - OrganizationName: pulumi.String("org"), - ProjectName: pulumi.String("network"), - StackName: pulumi.String("prod"), - Format: pulumiservice.WebhookFormatPulumiDeployments, - PayloadUrl: pulumi.String("database/prod"), - Active: pulumi.Bool(true), - DisplayName: pulumi.String("deploy-database"), - Filters: pulumiservice.WebhookFiltersArray{ - pulumiservice.WebhookFiltersUpdateSucceeded, - }, - }) - if err != nil { - return err - } - _, err = pulumiservice.NewWebhook(ctx, "computeWebhook", &pulumiservice.WebhookArgs{ - OrganizationName: pulumi.String("org"), - ProjectName: pulumi.String("database"), - StackName: pulumi.String("prod"), - Format: pulumiservice.WebhookFormatPulumiDeployments, - PayloadUrl: pulumi.String("compute/prod"), - Active: pulumi.Bool(true), - DisplayName: pulumi.String("deploy-compute"), - Filters: pulumiservice.WebhookFiltersArray{ - pulumiservice.WebhookFiltersUpdateSucceeded, - }, - }) - if err != nil { - return err - } - return nil - }) -} -``` - -{{% /choosable %}} - -{{% choosable language yaml %}} - -```yaml -name: auto-deploy-demo -runtime: yaml -description: A simple auto-deploy example -resources: - databaseWebhook: - type: pulumiservice:Webhook - properties: - organizationName: org - projectName: network - stackName: prod - format: pulumi_deployments - payloadUrl: database/prod - active: true - displayName: deploy-database - filters: - - update_succeeded - computeWebhook: - type: pulumiservice:Webhook - properties: - organizationName: org - projectName: database - stackName: prod - format: pulumi_deployments - payloadUrl: compute/prod - active: true - displayName: deploy-compute - filters: - - update_succeeded -``` - -{{% /choosable %}} - -{{< /chooser >}} - -#### Pulumi Auto Deploy - -[`Pulumi Auto Deploy`](/registry/packages/auto-deploy) lets you simply express dependencies between stacks, and takes care of creating and updating the necessary Deployment Webhooks under the hood. - -{{< chooser language "typescript,python,go,csharp,yaml" >}} - -{{% choosable language typescript %}} - -```ts -import * as autodeploy from "@pulumi/auto-deploy"; -import * as pulumi from "@pulumi/pulumi"; - -/** - * - * The following example configures automatic deployment of stacks with the following dependency graph: - a - ├── b - │ ├── d - │ ├── e - │ └── f - └── c - * Whenever a node in the graph is updated, - * all downstream nodes will be automatically updated via a webhook triggering Pulumi Deployments. - */ - -const organization = pulumi.getOrganization(); -const project = "dependency-example" - -export const f = new autodeploy.AutoDeployer("auto-deployer-f", { - organization, - project, - stack: "f", - downstreamRefs: [], -}); - -export const e = new autodeploy.AutoDeployer("auto-deployer-e", { - organization, - project, - stack: "e", - downstreamRefs: [], -}); - -export const d = new autodeploy.AutoDeployer("auto-deployer-d", { - organization, - project, - stack: "d", - downstreamRefs: [], -}); - -export const c = new autodeploy.AutoDeployer("auto-deployer-c", { - organization, - project, - stack: "c", - downstreamRefs: [], -}); - -export const b = new autodeploy.AutoDeployer("auto-deployer-b", { - organization, - project, - stack: "b", - downstreamRefs: [d.ref, e.ref, f.ref], - -}); - -export const a = new autodeploy.AutoDeployer("auto-deployer-a", { - organization, - project, - stack: "a", - downstreamRefs: [b.ref, c.ref], -}); -``` - -{{% /choosable %}} -{{% choosable language csharp %}} - -```csharp -using System.Collections.Generic; -using System.Linq; -using Pulumi; -using AutoDeploy = Pulumi.AutoDeploy; - -/** - * - * The following example configures automatic deployment of stacks with the following dependency graph: - a - ├── b - │ ├── d - │ ├── e - │ └── f - └── c - * Whenever a node in the graph is updated, - * all downstream nodes will be automatically updated via a webhook triggering Pulumi Deployments. - */ - -return await Deployment.RunAsync(() => -{ - var projectVar = "dependency-example"; - - var organization = "pulumi"; - - var f = new AutoDeploy.AutoDeployer("f", new() - { - Organization = organization, - Project = projectVar, - Stack = "f", - DownstreamRefs = new[] {}, - }); - - var e = new AutoDeploy.AutoDeployer("e", new() - { - Organization = organization, - Project = projectVar, - Stack = "e", - DownstreamRefs = new[] {}, - }); - - var d = new AutoDeploy.AutoDeployer("d", new() - { - Organization = organization, - Project = projectVar, - Stack = "d", - DownstreamRefs = new[] {}, - }); - - var c = new AutoDeploy.AutoDeployer("c", new() - { - Organization = organization, - Project = projectVar, - Stack = "c", - DownstreamRefs = new[] {}, - }); - - var b = new AutoDeploy.AutoDeployer("b", new() - { - Organization = organization, - Project = projectVar, - Stack = "b", - DownstreamRefs = new[] - { - d.Ref, - e.Ref, - f.Ref, - }, - }); - - var a = new AutoDeploy.AutoDeployer("a", new() - { - Organization = organization, - Project = projectVar, - Stack = "a", - DownstreamRefs = new[] - { - b.Ref, - c.Ref, - }, - }); - -}); -``` - -{{% /choosable %}} - -{{% choosable language python %}} - -```python -import pulumi -import pulumi_auto_deploy as auto_deploy - -''' - -The following example configures automatic deployment of stacks with the following dependency graph: - a - ├── b - │ ├── d - │ ├── e - │ └── f - └── c -Whenever a node in the graph is updated, -all downstream nodes will be automatically updated via a webhook triggering Pulumi Deployments. -''' - -project_var = "dependency-example" -organization = pulumi.get_organization() -f = auto_deploy.AutoDeployer("f", - organization=organization, - project=project_var, - stack="f", - downstream_refs=[]) -e = auto_deploy.AutoDeployer("e", - organization=organization, - project=project_var, - stack="e", - downstream_refs=[]) -d = auto_deploy.AutoDeployer("d", - organization=organization, - project=project_var, - stack="d", - downstream_refs=[]) -c = auto_deploy.AutoDeployer("c", - organization=organization, - project=project_var, - stack="c", - downstream_refs=[]) -b = auto_deploy.AutoDeployer("b", - organization=organization, - project=project_var, - stack="b", - downstream_refs=[ - d.ref, - e.ref, - f.ref, - ]) -a = auto_deploy.AutoDeployer("a", - organization=organization, - project=project_var, - stack="a", - downstream_refs=[ - b.ref, - c.ref, - ]) -``` - -{{% /choosable %}} - -{{% choosable language go %}} - -```go -package main - -import ( - "github.com/pulumi/pulumi-auto-deploy/sdk/go/autodeploy" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi" -) - -func main() { - /** - * - * The following example configures automatic deployment of stacks with the following dependency graph: - a - ├── b - │ ├── d - │ ├── e - │ └── f - └── c - * Whenever a node in the graph is updated, - * all downstream nodes will be automatically updated via a webhook triggering Pulumi Deployments. - */ - - pulumi.Run(func(ctx *pulumi.Context) error { - projectVar := "dependency-example" - organization := "pulumi" - f, err := autodeploy.NewAutoDeployer(ctx, "f", &autodeploy.AutoDeployerArgs{ - Organization: pulumi.String(organization), - Project: pulumi.String(projectVar), - Stack: pulumi.String("f"), - DownstreamRefs: pulumi.StringArray{}, - }) - if err != nil { - return err - } - e, err := autodeploy.NewAutoDeployer(ctx, "e", &autodeploy.AutoDeployerArgs{ - Organization: pulumi.String(organization), - Project: pulumi.String(projectVar), - Stack: pulumi.String("e"), - DownstreamRefs: pulumi.StringArray{}, - }) - if err != nil { - return err - } - d, err := autodeploy.NewAutoDeployer(ctx, "d", &autodeploy.AutoDeployerArgs{ - Organization: pulumi.String(organization), - Project: pulumi.String(projectVar), - Stack: pulumi.String("d"), - DownstreamRefs: pulumi.StringArray{}, - }) - if err != nil { - return err - } - c, err := autodeploy.NewAutoDeployer(ctx, "c", &autodeploy.AutoDeployerArgs{ - Organization: pulumi.String(organization), - Project: pulumi.String(projectVar), - Stack: pulumi.String("c"), - DownstreamRefs: pulumi.StringArray{}, - }) - if err != nil { - return err - } - b, err := autodeploy.NewAutoDeployer(ctx, "b", &autodeploy.AutoDeployerArgs{ - Organization: pulumi.String(organization), - Project: pulumi.String(projectVar), - Stack: pulumi.String("b"), - DownstreamRefs: pulumi.StringArray{ - d.Ref, - e.Ref, - f.Ref, - }, - }) - if err != nil { - return err - } - _, err = autodeploy.NewAutoDeployer(ctx, "a", &autodeploy.AutoDeployerArgs{ - Organization: pulumi.String(organization), - Project: pulumi.String(projectVar), - Stack: pulumi.String("a"), - DownstreamRefs: pulumi.StringArray{ - b.Ref, - c.Ref, - }, - }) - if err != nil { - return err - } - return nil - }) -} -``` - -{{% /choosable %}} - -{{% choosable language yaml %}} - -```yaml -name: auto-deploy-demo -runtime: yaml -description: A simple auto-deploy example -variables: - project: dependency-example - # TODO: update once https://github.com/pulumi/pulumi-yaml/issues/461 is fixed - organization: pulumi -resources: - f: - type: auto-deploy:AutoDeployer - properties: - organization: ${organization} - project: ${project} - stack: f - downstreamRefs: [] - e: - type: auto-deploy:AutoDeployer - properties: - organization: ${organization} - project: ${project} - stack: e - downstreamRefs: [] - d: - type: auto-deploy:AutoDeployer - properties: - organization: ${organization} - project: ${project} - stack: d - downstreamRefs: [] - c: - type: auto-deploy:AutoDeployer - properties: - organization: ${organization} - project: ${project} - stack: c - downstreamRefs: [] - b: - type: auto-deploy:AutoDeployer - properties: - organization: ${organization} - project: ${project} - stack: b - downstreamRefs: - - ${d.ref} - - ${e.ref} - - ${f.ref} - a: - type: auto-deploy:AutoDeployer - properties: - organization: ${organization} - project: ${project} - stack: a - downstreamRefs: - - ${b.ref} - - ${c.ref} -``` - -{{% /choosable %}} - -{{< /chooser >}} diff --git a/content/docs/pulumi-cloud/deployments/using/_index.md b/content/docs/pulumi-cloud/deployments/using/_index.md new file mode 100644 index 000000000000..81d734bf182d --- /dev/null +++ b/content/docs/pulumi-cloud/deployments/using/_index.md @@ -0,0 +1,45 @@ +--- +title_tag: "Using Pulumi Deployments" +meta_desc: Learn how to configure and use Pulumi Deployments to automate your infrastructure deployments +title: "Using Deployments" +h1: "Using Pulumi Deployments" +meta_image: /images/docs/meta-images/docs-meta.png +menu: + cloud: + name: Using Deployments + parent: pulumi-cloud-deployments + weight: 2 + identifier: pulumi-cloud-deployments-using +aliases: + - /docs/intro/deployments/reference/ + - /docs/pulumi-cloud/deployments/reference/ + - /docs/pulumi-cloud/deployments/using-deployments/ +--- + +This page provides an overview of how to use Pulumi Deployments to automate your infrastructure deployments. + +## Getting Started with Deployments + +Pulumi Deployments are configured on a per-stack basis. To use Deployments effectively, follow these steps: + +1. **Configure Deployment Settings**: First, set up your [deployment settings](./settings) which include source code location, cloud credentials, environment variables, and build requirements. +1. **Set Up Triggers**: Configure how [deployment triggers](./triggers) are initiated. A common pattern is to: + - Run a `pulumi preview` when a PR is created + - Run a `pulumi up` when a PR is merged to main +1. **Expand Your Usage**: As you grow more comfortable with Deployments, consider using additional features: + - [Drift detection](../drift) to automatically detect when your infrastructure differs from its desired state + - [Review stacks](../review-stacks) for temporary environments on PRs + - [TTL stacks](../ttl) for ephemeral environments + - [Post-deployment automation](./post-automation) to create webhooks to trigger additional actions, like updating additional stacks + - [Webhooks](/docs/pulumi-cloud/webhooks/#deployment-webhooks) for custom automation + +## Automating at Scale + +For teams managing many stacks or platforms serving multiple teams, you can automate Deployments at scale using: + +- The **[Pulumi Cloud Provider](/registry/packages/pulumiservice/api-docs/deploymentsettings)**: Manage deployment settings as code +- The **[REST API](../api)**: Programmatically control all aspects of Deployments + +## Additional Resources + +- [Private Repositories and Packages](./private-repositories): Configure access to private Git repositories and package feeds diff --git a/content/docs/pulumi-cloud/deployments/using/post-automation.md b/content/docs/pulumi-cloud/deployments/using/post-automation.md new file mode 100644 index 000000000000..07165a558ea8 --- /dev/null +++ b/content/docs/pulumi-cloud/deployments/using/post-automation.md @@ -0,0 +1,599 @@ +--- +title_tag: "Post-Deployment Automation | Pulumi Deployments" +meta_desc: Learn how to configure post-deployment automation with Pulumi Deployments +title: "Post-Deployment Automation" +h1: "Post-Deployment Automation" +meta_image: /images/docs/meta-images/docs-meta.png +menu: + cloud: + parent: pulumi-cloud-deployments-using + weight: 4 +--- + +After a deployment completes successfully, you may want to trigger additional actions or deployments. Pulumi Deployments supports post-deployment automation through webhooks and the Auto Deploy package. + +## Deploying Dependent Stacks + +Pulumi Deployments can be used to automatically deploy dependent stacks via Deployment Webhooks. This enables you to keep your infrastructure up-to-date across stack reference boundaries. This can be configured in one of two ways: + +1. [Deployment Webhook Destinations](/docs/pulumi-cloud/webhooks/#deployment-webhooks) +2. [The Pulumi Auto Deploy Package](/registry/packages/auto-deploy) + +Either method requires that your stacks are configured with [Deployment Settings](./settings). + +### Deployment Webhook Destinations + +[Deployment Webhook Destinations](/docs/pulumi-cloud/webhooks/#deployment-webhooks) allow you to pick one or more event types on a stack (i.e. `update succeeded`, or `refresh failed`) and automatically deliver an event to a destination - in this case the Create Deployment API for another Stack. + +{{< chooser language "typescript,python,go,csharp,yaml" >}} + +{{% choosable language typescript %}} + +```ts +import * as pulumi from "@pulumi/pulumi"; +import * as pulumiservice from "@pulumi/pulumiservice"; + +const databaseWebhook = new pulumiservice.Webhook("databaseWebhook", { + organizationName: "org", + projectName: "network", + stackName: "prod", + format: pulumiservice.WebhookFormat.PulumiDeployments, + payloadUrl: "database/prod", + active: true, + displayName: "deploy-database", + filters: [pulumiservice.WebhookFilters.UpdateSucceeded], +}); +const computeWebhook = new pulumiservice.Webhook("computeWebhook", { + organizationName: "org", + projectName: "database", + stackName: "prod", + format: pulumiservice.WebhookFormat.PulumiDeployments, + payloadUrl: "compute/prod", + active: true, + displayName: "deploy-compute", + filters: [pulumiservice.WebhookFilters.UpdateSucceeded], +}); +``` + +{{% /choosable %}} +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using PulumiService = Pulumi.PulumiService; + +return await Deployment.RunAsync(() => +{ + var databaseWebhook = new PulumiService.Webhook("databaseWebhook", new() + { + OrganizationName = "org", + ProjectName = "network", + StackName = "prod", + Format = PulumiService.WebhookFormat.PulumiDeployments, + PayloadUrl = "database/prod", + Active = true, + DisplayName = "deploy-database", + Filters = new[] + { + PulumiService.WebhookFilters.UpdateSucceeded, + }, + }); + + var computeWebhook = new PulumiService.Webhook("computeWebhook", new() + { + OrganizationName = "org", + ProjectName = "database", + StackName = "prod", + Format = PulumiService.WebhookFormat.PulumiDeployments, + PayloadUrl = "compute/prod", + Active = true, + DisplayName = "deploy-compute", + Filters = new[] + { + PulumiService.WebhookFilters.UpdateSucceeded, + }, + }); + +}); +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_pulumiservice as pulumiservice + +database_webhook = pulumiservice.Webhook("databaseWebhook", + organization_name="org", + project_name="network", + stack_name="prod", + format=pulumiservice.WebhookFormat.PULUMI_DEPLOYMENTS, + payload_url="database/prod", + active=True, + display_name="deploy-database", + filters=[pulumiservice.WebhookFilters.UPDATE_SUCCEEDED]) +compute_webhook = pulumiservice.Webhook("computeWebhook", + organization_name="org", + project_name="database", + stack_name="prod", + format=pulumiservice.WebhookFormat.PULUMI_DEPLOYMENTS, + payload_url="compute/prod", + active=True, + display_name="deploy-compute", + filters=[pulumiservice.WebhookFilters.UPDATE_SUCCEEDED]) +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-pulumiservice/sdk/go/pulumiservice" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := pulumiservice.NewWebhook(ctx, "databaseWebhook", &pulumiservice.WebhookArgs{ + OrganizationName: pulumi.String("org"), + ProjectName: pulumi.String("network"), + StackName: pulumi.String("prod"), + Format: pulumiservice.WebhookFormatPulumiDeployments, + PayloadUrl: pulumi.String("database/prod"), + Active: pulumi.Bool(true), + DisplayName: pulumi.String("deploy-database"), + Filters: pulumiservice.WebhookFiltersArray{ + pulumiservice.WebhookFiltersUpdateSucceeded, + }, + }) + if err != nil { + return err + } + _, err = pulumiservice.NewWebhook(ctx, "computeWebhook", &pulumiservice.WebhookArgs{ + OrganizationName: pulumi.String("org"), + ProjectName: pulumi.String("database"), + StackName: pulumi.String("prod"), + Format: pulumiservice.WebhookFormatPulumiDeployments, + PayloadUrl: pulumi.String("compute/prod"), + Active: pulumi.Bool(true), + DisplayName: pulumi.String("deploy-compute"), + Filters: pulumiservice.WebhookFiltersArray{ + pulumiservice.WebhookFiltersUpdateSucceeded, + }, + }) + if err != nil { + return err + } + return nil + }) +} +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: auto-deploy-demo +runtime: yaml +description: A simple auto-deploy example +resources: + databaseWebhook: + type: pulumiservice:Webhook + properties: + organizationName: org + projectName: network + stackName: prod + format: pulumi_deployments + payloadUrl: database/prod + active: true + displayName: deploy-database + filters: + - update_succeeded + computeWebhook: + type: pulumiservice:Webhook + properties: + organizationName: org + projectName: database + stackName: prod + format: pulumi_deployments + payloadUrl: compute/prod + active: true + displayName: deploy-compute + filters: + - update_succeeded +``` + +{{% /choosable %}} + +{{< /chooser >}} + +### Pulumi Auto Deploy + +[`Pulumi Auto Deploy`](/registry/packages/auto-deploy) lets you simply express dependencies between stacks, and takes care of creating and updating the necessary Deployment Webhooks under the hood. + +{{< chooser language "typescript,python,go,csharp,yaml" >}} + +{{% choosable language typescript %}} + +```ts +import * as autodeploy from "@pulumi/auto-deploy"; +import * as pulumi from "@pulumi/pulumi"; + +/** + * + * The following example configures automatic deployment of stacks with the following dependency graph: + a + ├── b + │ ├── d + │ ├── e + │ └── f + └── c + * Whenever a node in the graph is updated, + * all downstream nodes will be automatically updated via a webhook triggering Pulumi Deployments. + */ + +const organization = pulumi.getOrganization(); +const project = "dependency-example" + +export const f = new autodeploy.AutoDeployer("auto-deployer-f", { + organization, + project, + stack: "f", + downstreamRefs: [], +}); + +export const e = new autodeploy.AutoDeployer("auto-deployer-e", { + organization, + project, + stack: "e", + downstreamRefs: [], +}); + +export const d = new autodeploy.AutoDeployer("auto-deployer-d", { + organization, + project, + stack: "d", + downstreamRefs: [], +}); + +export const c = new autodeploy.AutoDeployer("auto-deployer-c", { + organization, + project, + stack: "c", + downstreamRefs: [], +}); + +export const b = new autodeploy.AutoDeployer("auto-deployer-b", { + organization, + project, + stack: "b", + downstreamRefs: [d.ref, e.ref, f.ref], + +}); + +export const a = new autodeploy.AutoDeployer("auto-deployer-a", { + organization, + project, + stack: "a", + downstreamRefs: [b.ref, c.ref], +}); +``` + +{{% /choosable %}} +{{% choosable language csharp %}} + +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using AutoDeploy = Pulumi.AutoDeploy; + +/** + * + * The following example configures automatic deployment of stacks with the following dependency graph: + a + ├── b + │ ├── d + │ ├── e + │ └── f + └── c + * Whenever a node in the graph is updated, + * all downstream nodes will be automatically updated via a webhook triggering Pulumi Deployments. + */ + +return await Deployment.RunAsync(() => +{ + var projectVar = "dependency-example"; + + var organization = "pulumi"; + + var f = new AutoDeploy.AutoDeployer("f", new() + { + Organization = organization, + Project = projectVar, + Stack = "f", + DownstreamRefs = new[] {}, + }); + + var e = new AutoDeploy.AutoDeployer("e", new() + { + Organization = organization, + Project = projectVar, + Stack = "e", + DownstreamRefs = new[] {}, + }); + + var d = new AutoDeploy.AutoDeployer("d", new() + { + Organization = organization, + Project = projectVar, + Stack = "d", + DownstreamRefs = new[] {}, + }); + + var c = new AutoDeploy.AutoDeployer("c", new() + { + Organization = organization, + Project = projectVar, + Stack = "c", + DownstreamRefs = new[] {}, + }); + + var b = new AutoDeploy.AutoDeployer("b", new() + { + Organization = organization, + Project = projectVar, + Stack = "b", + DownstreamRefs = new[] + { + d.Ref, + e.Ref, + f.Ref, + }, + }); + + var a = new AutoDeploy.AutoDeployer("a", new() + { + Organization = organization, + Project = projectVar, + Stack = "a", + DownstreamRefs = new[] + { + b.Ref, + c.Ref, + }, + }); + +}); +``` + +{{% /choosable %}} + +{{% choosable language python %}} + +```python +import pulumi +import pulumi_auto_deploy as auto_deploy + +''' + +The following example configures automatic deployment of stacks with the following dependency graph: + a + ├── b + │ ├── d + │ ├── e + │ └── f + └── c +Whenever a node in the graph is updated, +all downstream nodes will be automatically updated via a webhook triggering Pulumi Deployments. +''' + +project_var = "dependency-example" +organization = pulumi.get_organization() +f = auto_deploy.AutoDeployer("f", + organization=organization, + project=project_var, + stack="f", + downstream_refs=[]) +e = auto_deploy.AutoDeployer("e", + organization=organization, + project=project_var, + stack="e", + downstream_refs=[]) +d = auto_deploy.AutoDeployer("d", + organization=organization, + project=project_var, + stack="d", + downstream_refs=[]) +c = auto_deploy.AutoDeployer("c", + organization=organization, + project=project_var, + stack="c", + downstream_refs=[]) +b = auto_deploy.AutoDeployer("b", + organization=organization, + project=project_var, + stack="b", + downstream_refs=[ + d.ref, + e.ref, + f.ref, + ]) +a = auto_deploy.AutoDeployer("a", + organization=organization, + project=project_var, + stack="a", + downstream_refs=[ + b.ref, + c.ref, + ]) +``` + +{{% /choosable %}} + +{{% choosable language go %}} + +```go +package main + +import ( + "github.com/pulumi/pulumi-auto-deploy/sdk/go/autodeploy" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + /** + * + * The following example configures automatic deployment of stacks with the following dependency graph: + a + ├── b + │ ├── d + │ ├── e + │ └── f + └── c + * Whenever a node in the graph is updated, + * all downstream nodes will be automatically updated via a webhook triggering Pulumi Deployments. + */ + + pulumi.Run(func(ctx *pulumi.Context) error { + projectVar := "dependency-example" + organization := "pulumi" + f, err := autodeploy.NewAutoDeployer(ctx, "f", &autodeploy.AutoDeployerArgs{ + Organization: pulumi.String(organization), + Project: pulumi.String(projectVar), + Stack: pulumi.String("f"), + DownstreamRefs: pulumi.StringArray{}, + }) + if err != nil { + return err + } + e, err := autodeploy.NewAutoDeployer(ctx, "e", &autodeploy.AutoDeployerArgs{ + Organization: pulumi.String(organization), + Project: pulumi.String(projectVar), + Stack: pulumi.String("e"), + DownstreamRefs: pulumi.StringArray{}, + }) + if err != nil { + return err + } + d, err := autodeploy.NewAutoDeployer(ctx, "d", &autodeploy.AutoDeployerArgs{ + Organization: pulumi.String(organization), + Project: pulumi.String(projectVar), + Stack: pulumi.String("d"), + DownstreamRefs: pulumi.StringArray{}, + }) + if err != nil { + return err + } + c, err := autodeploy.NewAutoDeployer(ctx, "c", &autodeploy.AutoDeployerArgs{ + Organization: pulumi.String(organization), + Project: pulumi.String(projectVar), + Stack: pulumi.String("c"), + DownstreamRefs: pulumi.StringArray{}, + }) + if err != nil { + return err + } + b, err := autodeploy.NewAutoDeployer(ctx, "b", &autodeploy.AutoDeployerArgs{ + Organization: pulumi.String(organization), + Project: pulumi.String(projectVar), + Stack: pulumi.String("b"), + DownstreamRefs: pulumi.StringArray{ + d.Ref, + e.Ref, + f.Ref, + }, + }) + if err != nil { + return err + } + _, err = autodeploy.NewAutoDeployer(ctx, "a", &autodeploy.AutoDeployerArgs{ + Organization: pulumi.String(organization), + Project: pulumi.String(projectVar), + Stack: pulumi.String("a"), + DownstreamRefs: pulumi.StringArray{ + b.Ref, + c.Ref, + }, + }) + if err != nil { + return err + } + return nil + }) +} +``` + +{{% /choosable %}} + +{{% choosable language yaml %}} + +```yaml +name: auto-deploy-demo +runtime: yaml +description: A simple auto-deploy example +variables: + project: dependency-example + # TODO: update once https://github.com/pulumi/pulumi-yaml/issues/461 is fixed + organization: pulumi +resources: + f: + type: auto-deploy:AutoDeployer + properties: + organization: ${organization} + project: ${project} + stack: f + downstreamRefs: [] + e: + type: auto-deploy:AutoDeployer + properties: + organization: ${organization} + project: ${project} + stack: e + downstreamRefs: [] + d: + type: auto-deploy:AutoDeployer + properties: + organization: ${organization} + project: ${project} + stack: d + downstreamRefs: [] + c: + type: auto-deploy:AutoDeployer + properties: + organization: ${organization} + project: ${project} + stack: c + downstreamRefs: [] + b: + type: auto-deploy:AutoDeployer + properties: + organization: ${organization} + project: ${project} + stack: b + downstreamRefs: + - ${d.ref} + - ${e.ref} + - ${f.ref} + a: + type: auto-deploy:AutoDeployer + properties: + organization: ${organization} + project: ${project} + stack: a + downstreamRefs: + - ${b.ref} + - ${c.ref} +``` + +{{% /choosable %}} + +{{< /chooser >}} diff --git a/content/docs/pulumi-cloud/deployments/using/private-repositories.md b/content/docs/pulumi-cloud/deployments/using/private-repositories.md new file mode 100644 index 000000000000..29ecd14774c1 --- /dev/null +++ b/content/docs/pulumi-cloud/deployments/using/private-repositories.md @@ -0,0 +1,34 @@ +--- +title_tag: "Private Git Repositories | Pulumi Deployments" +meta_desc: Learn how to configure Pulumi Deployments to access private Git repositories +title: "Private Git Repositories" +h1: "Private Git Repositories" +meta_image: /images/docs/meta-images/docs-meta.png +menu: + cloud: + parent: pulumi-cloud-deployments-using + weight: 3 +--- + +When working with Pulumi Deployments, you may need to access private Git repositories. + +## Private Dependency Packages + +If your Pulumi Deployment requires access to private GitHub repositories, e.g. your program uses a private Go module, it is necessary to configure an SSH key with access to the required repos. Without the correct configuration, the Deployment will be unable to access those private artifacts, and the deployment may fail. + +The following will allow you to configure a private key and allow access to GitHub using SSH to pull down the appropriate artifacts properly: + +1. Add the following code into the `Pre-run commands` and toggle on `Skip automatic dependency installation step` in Advanced Settings: + + ```bash + mkdir /root/.ssh && printf -- "$SSHKEY" > /root/.ssh/id_ed25519 + chmod 600 /root/.ssh/id_ed25519 + ssh-keyscan github.com >> ~/.ssh/known_hosts + cd .. && git config --global --add url.\"git@github.com:\".insteadOf \"https://github.com\" + ``` + + ![SSH Key Prerun Command](../../limit-prerun-cmd.png) + +2. Add the `$SSHKEY` field as a secret environment variable: + +![SSH Key Env Variable](../../limit-env.png) diff --git a/content/docs/pulumi-cloud/deployments/using/settings.md b/content/docs/pulumi-cloud/deployments/using/settings.md new file mode 100644 index 000000000000..880a08decf7d --- /dev/null +++ b/content/docs/pulumi-cloud/deployments/using/settings.md @@ -0,0 +1,175 @@ +--- +title_tag: "Deployment Settings | Pulumi Deployments" +meta_desc: Learn how to configure Deployment Settings for Pulumi Deployments +title: "Deployment Settings" +h1: "Deployment Settings" +meta_image: /images/docs/meta-images/docs-meta.png +menu: + cloud: + parent: pulumi-cloud-deployments-using + weight: 1 +--- + +Deployment settings refer to the full set of configuration required to run a Pulumi Deployment, defined on a per-stack basis. These settings can be managed through the Pulumi Cloud UI, via the REST API, or defined as code with the Pulumi Cloud provider. + +## Creating Deployment Settings + +You can create and manage deployment settings in several ways: + +### From the Pulumi Cloud UI + +From the Pulumi Console, a stack's deployment settings can be accessed via the `Settings > Deploy` tab. Once the settings are defined via the UI, they apply to all Deployment triggers, including push-to-deploy (if you have the GitHub app installed), click-to-deploy and the REST API. + +![Pulumi UI - Deployment Settings](../../ui-settings.png) + +### From the API + +Alternatively, a stack's deployment settings may be defined and subsequently modified using the REST API. For more information, see [Patch Settings](/docs/pulumi-cloud/reference/deployments/#patch-settings) in the [Pulumi Deployments REST API docs](/docs/pulumi-cloud/reference/deployments). + +### Defined as Code with the Pulumi Cloud provider + +Finally, a stack's deployment settings may be defined as a resource within the stack itself using the Pulumi Cloud provider. This lets you securely store your settings in source control alongside your code. For more information, see the [`pulumiservice.DeploymentSettings`](https://www.pulumi.com/registry/packages/pulumiservice/api-docs/deploymentsettings/) resource docs in the [Pulumi Registry](/registry). + +{{% notes type="info" %}} +Pulumi recommends against a stack defining its own Deployment Settings (that is, containing a `pulumiService.DeploymentSettings` resource that for itself), as this would require two deployments for the settings changes to take effect. Instead, consider creating a separate Pulumi program that defines Deployment Settings for multiple stacks that share similar configuration. +{{% /notes %}} + +## Path Filtering + +When using the GitHub app and push-to-deploy, you may want to filter deployment events to only target file changes in specific directories. You can easily do this using path filtering, so a deployment is only triggered if there is a change in files that match the path filters. This is especially useful for monorepos where you may have multiple Pulumi programs within the same repository. + +Path filters are relative to the repository root, and should reference a file by name or a directory must reference files by name relative to the repository or directories via glob patterns such as `/**` to include all changes within a directory. + +![Pulumi UI - Path Filters](../../ui-path-filters.png) + +As with any other deployment setting, the path filters may be set via the Pulumi Console, using the REST API or defined in code using the Pulumi Cloud provider. + +## Deployment Runner Pools + +When using Pulumi Deployments, you have options for where your deployments run: + +- **Default Runner Pool**: Managed by Pulumi and available to all Pulumi Cloud customers +- **Customer-Managed Agents**: Self-hosted runners that can access private networks and resources + +For more information on customer-managed agents, see the [Customer Managed Agents documentation](../../customer-managed-agents). + +## Pre-Run Commands + +Pre-run commands allow you to execute arbitrary shell commands before the deployment process starts. This is useful for environment setup, authentication with private package repositories, or other preparatory work. + +For example, you might use pre-run commands to: + +- Install additional dependencies +- Configure authentication for private repositories +- Generate configuration files +- Set up environment variables + +Pre-run commands can be configured through the UI, REST API, or as code with the Pulumi Cloud provider. + +{{% notes type="info" %}} +You can use Pulumi ESC with pre-run commands by prefixing each command with `pulumi env run`. For example: + +```bash +pulumi env run my-aws-env -- aws s3 ls +``` + +This executes the `aws s3 ls` command with credentials from your `my-aws-env` ESC environment. See the [Pulumi ESC CLI documentation](/docs/esc/usage/cli-commands/#env) for more details. +{{% /notes %}} + +## Skipping Automatic Dependency Installation + +By default, the deployment executor will attempt to install dependencies for your project by using the default dependency manager for the language (i.e. `npm` for nodejs or `virtualenv` for python). However, there may be scenarios where you may want to have more control over the dependency installation step (e.g. you are using `yarn` and/or a different version of `node` than the one that is installed by default). + +This is enabled by skipping the default dependency installation step (under Advanced Settings in the UI), and setting a few pre-run commands and environment variables. + +![Pulumi UI - Node Version](../../ui-node-version.png) + +## Skipping Intermediate Deployments + +By default, when multiple deployments are pushed, they will be executed sequentially until the backlog is completed. In some cases, you may wish to only execute the most recent deployment since the changes are accumulative. By enabling the `Skip intermediate deployments` setting, Pulumi will skip all intermediary deployments of the same type and will execute only the latest. + +![Pulumi UI - Skip intermediate deployments](../../ui-skip-intermediate-deployments.png) + +## Custom Executor Images + +By default, the deployment is executed using the [pulumi/pulumi](https://hub.docker.com/r/pulumi/pulumi) image. +The pulumi/pulumi image is a unix-based image which includes the pulumi CLI in its `$PATH` and the [LTS versions](https://github.com/pulumi/pulumi-docker-containers/blob/main/README.md#version-policy) of all supported SDK runtime(s) for your Pulumi program. + +However, there may be scenarios where you might want to customize the image used for the execution, e.g. if you want to use a different version of python or need to include additional dependencies. + +This is possible by specifying a custom executor image for your deployment. Using the custom executor image field, you can pin to a specific version of the pulumi/pulumi image, +or point to a completely custom image hosted in a public or private container registry. + +![Pulumi UI - Custom Executor](../../ui-custom-executor.png) + +Image requirements: + +- It must be a unix-based image which includes `curl`. +- It must include the `pulumi` CLI in its `$PATH`. +- It must include the required SDK runtime(s) for your Pulumi program. + +{{% notes "info" %}} +Using a custom image may result in slower execution due to time spent pulling the image. + +Additionally, we only support static credentials in custom executor images. +{{% /notes %}} + +## Open ID Connect (OIDC) + +Pulumi Deployments supports OIDC for authenticating with cloud providers. This enables your deployments to access your cloud resources without storing static credentials in Pulumi Cloud. + +For details on supported clouds see [OIDC Setup for Pulumi Deployments](/docs/pulumi-cloud/deployments/oidc/). + +## Dependency Caching + +When using Pulumi-managed deployment agents, you have the option to speed up deployments using dependency caching. + +The caching method is simple: during the first deployment, the deployment agent will automatically detect downloaded dependencies using lock files, zip them up and store the archive in blob storage. During all subsequent deployments, agents will pull such an archive down and unpack it, saving time it would normally take to download those dependencies. When your dependencies change, deployment agents will automatically invalidate the old cache and create a new one. + +Caches are shared on the project level, so all stacks within a project can share the same cache. However, caches are fully isolated and never shared between customers. + +Dependency caching is supported for the following runtimes: + +- `.NET` - no special configuration required +- `Python` - ensure that you have `requirements.txt` in the root of your source code. +- `Go` - ensure that you have `go.mod` and `go.sum` in the root of your source code. +- `NodeJS` - ensure that you have `packageManager` field specified in `package.json`. For now, only `npm` and `yarn` are supported. + - For `npm`, ensure that you have `package-lock.json` in the root of your source code. + - For `yarn`, ensure that you have `yarn.lock` in the root of your source code. + +To confirm dependency caching is working and/or to troubleshoot, check out logs of your deployments, specifically the `Restore Cache` and `Save Cache` steps. + +## Environment Variables + +By default, there are a set of environment variables set by the process automatically: + +- `GITHUB_TOKEN`: Personal Access Token configured when the source is GitHub (unless there is a token configured by the custom environment variables) +- `PULUMI_ACCESS_TOKEN`: A temporary token with read-write access only to the stack being deployed. +- `PULUMI_DEPLOY_OIDC_CONFIG`: OIDC configuration provided for the cloud integrations +- `PULUMI_CI_SYSTEM`: "Pulumi Deployments" +- `PULUMI_CI_BUILD_ID`: Current deployment ID +- `PULUMI_CI_BUILD_NUMBER`: Current deployment version +- `PULUMI_CI_BUILD_URL`: Current deployment URL +- `PULUMI_CI_ORGANIZATION`: Current account organization +- `PULUMI_CI_PROJECT`: Current project name +- `PULUMI_CI_STACK`: Current stack name + +These can be overridden or extended by configuring custom environment variables: + +![Pulumi UI - Environment Variables](../../ui-custom-env-variables.png) + +### PULUMI_ENV + +Environment variables can be persisted between pre-run commands and the final pulumi deployment by appending them to the file on the file system named `PULUMI_ENV`. + +Example Usage: + +```bash +export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) +echo GOOGLE_OAUTH_ACCESS_TOKEN=$GOOGLE_OAUTH_ACCESS_TOKEN >> /PULUMI_ENV +``` + +Running `env` in a subsequent pre-run command will show the environment variable and it should be usable by scripts or your pulumi program. +{{% notes type="info" %}} +If `/PULUMI_ENV` does not work, and you are on self hosted, you can look for the following message in the logs to get the location: `Loading PULUMI_ENV from`. +{{% /notes %}} diff --git a/content/docs/pulumi-cloud/deployments/using/triggers.md b/content/docs/pulumi-cloud/deployments/using/triggers.md new file mode 100644 index 000000000000..326472fc6bb8 --- /dev/null +++ b/content/docs/pulumi-cloud/deployments/using/triggers.md @@ -0,0 +1,89 @@ +--- +title_tag: "Deployment Triggers | Pulumi Deployments" +meta_desc: Learn how to configure and use Deployment Triggers for Pulumi Deployments +title: "Deployment Triggers" +h1: "Deployment Triggers" +meta_image: /images/docs/meta-images/docs-meta.png +menu: + cloud: + parent: pulumi-cloud-deployments-using + weight: 2 +--- + +A deployment trigger is a method of initializing a deployment. + +## Available Deployments Triggers + +Deployments may be triggered in the following ways: + +- **[Click to Deploy](#click-to-deploy):** Run any Deployments operation on demand by clicking a button in the Pulumi Cloud console UI +- **[GitHub Push to Deploy](#github-push-to-deploy):** Automatically run a `pulumi preview` when a Pull Request is created and/or run `pulumi up` when a Pull Request is merged +- **[Review Stacks](#review-stacks):** Create and deploy an ephemeral stack on the current branch whenever a new Pull Request is created, and tear it down automatically once the Pull Request is merged +- **[Scheduled Deployments](#scheduled-deployments):** Run any Deployments operation on a recurring basis +- **[TTL Stacks](#ttl-stacks):** Run `pulumi destroy` on a stack (and optionally delete the stack entirely) after a specific amount of time has passed +- **[REST API](#rest-api):** Run any Deployments operation on demand programmatically by issuing an HTTP request against the Pulumi Deployments REST API +- **[Deployment Webhooks](#deployment-webhooks):** Trigger a Deployments operation in response to an event on another stack + +## Available Deployments Operations + +Pulumi Deployments supports the following operations: + +- **Update:** Run the `pulumi up` command to create or update stack resources +- **Preview:** Review changes by running the `pulumi preview` command +- **Refresh:** Update your stack's state file with the current state of your resources from your cloud provider by running the `pulumi refresh` command +- **Destroy:** Delete all resources in your stack by running the `pulumi destroy` command +- **Detect drift:** Refresh your stack's state file with the `pulumi refresh` command and fail if any changes are detected +- **Remediate drift:** Refresh your stack's state file and ensure that the state of your resources matches the declared state in your Pulumi program via the `pulumi update --refresh` command + +Note that not every operation is available for every trigger. + +## Click to Deploy + +A deployment may be triggered on demand by clicking a button in the Pulumi Console. This deployment trigger allows you to perform any supported Pulumi Deployments operation. + +![Pulumi UI - Click to Deploy](../../ui-deploy-button.png) + +## GitHub Push to Deploy + +{{% notes type="info" %}} +Push to Deploy requires the [Pulumi GitHub App](/docs/iac/using-pulumi/continuous-delivery/github-app/#installation-and-configuration) be installed to your GitHub organization. The app requires read access to your repos so it can clone your Pulumi programs and listen to merge commits to automatically trigger deployments on `git push`. +{{% /notes %}} + +Pulumi Deployments can run a `pulumi preview` for a stack (e.g., `dev`) when a Pull Request is opened against a particular git branch (e.g., a proposed change to the `main` branch). This will give the reviewer the full context necessary to understand the impact of the changes in your Pull Request: both the code changes _and the changes to your resources_ (i.e., the `pulumi preview` output). The Pulumi GitHub app will create or update a comment on your Pull Request with the results of `pulumi preview`. + +{{% notes type="info" %}} +The `pulumi preview` on Pull Request capability requires that the Github user creating the Pull Request has their Github Organization Visibility set to `Public`. +{{% /notes %}} + +GitHub Push to Deploy can also be configured to run a `pulumi update` for a stack when changes are merged to a particular git branch. This feature is useful to enable continuous delivery, for example to a shared development or QA environment. + +## Scheduled Deployments + +[Scheduled Deployments](/docs/pulumi-cloud/deployments/schedules) allow you to define Pulumi Deployments operations that you want to occur on a regular basis. For example, you may want to schedule a nightly deployment for a shared QA environment. + +[Drift Detection](/docs/pulumi-cloud/deployments/drift) is a specialized case of a Scheduled Deployment that allows you to ensure that your declared state in your Pulumi program has not diverged from the actual state of your resources. + +## TTL Stacks + +[TTL (Time to Live) Stacks](/docs/pulumi-cloud/deployments/ttl) are temporary stacks that are automatically destroyed after a specified period of time. TTL Stacks are useful for controlling cloud costs and improving security posture by ensuring resources are torn down once they are no longer needed. + +## Review Stacks + +[Review Stacks](/docs/pulumi-cloud/deployments/review-stacks) are dedicated cloud environments that get created automatically every time a pull request is opened. Open a pull request, and Pulumi Deployments will stand up a stack with your changes and the Pulumi GitHub App will add a PR comment with the outputs from your deployment. Merge the PR and Pulumi Deployments will destroy the stack and free up the associated resources. + +![Review Stack Pull Request Comment](../../comment.png) + +## REST API + +The Pulumi Deployments REST API allows you to trigger a deployment programmatically. Your stack does not need to have any Deployments Settings pre-defined - you can pass them in as part of the request. Alternatively, if your stack does have defined Deployments Settings, you can override any values by passing them in as part of the request. + +For more information, see [Create Deployment](docs/pulumi-cloud/reference/deployments/#create-deployment) in the Pulumi Deployments REST API docs. + +## Deployment Webhooks + +[Deployment Webhooks](/docs/pulumi-cloud/webhooks/#deployment-webhooks) allow you to trigger Deployments on other stacks when a given event or occurs. Common use cases include: + +- Update a dependent stack when an upstream stack (e.g. one that is referenced via a Stack Reference) changes. +- Update a higher environment (e.g. staging) when a lower environment (e.g. QA) successfully updates. + +The [Pulumi Auto Deploy package](/registry/packages/auto-deploy) (currently in Preview) allows you to manage dependent stack updates in a declarative fashion.