Skip to main content
The provider block declares and configures a Pulumi provider for your stack. It supports version constraints, named aliases for multi-region or multi-account deployments, and per-resource routing via the provider meta-argument.
provider {} currently emits Pulumi Python provider instantiation code. When the native UBX engine (UBX-159) becomes the default backend, provider configuration will map to that engine’s provider model instead.

Syntax

Default provider

provider aws {
    region  = "us-east-1"
    version = ">= 6.0.0"
}
  • aws — bare identifier naming the provider type (not a quoted string)
  • version — optional semver constraint string; warn-only on unrecognized format
  • All other fields are forwarded to the Pulumi provider constructor

Aliased provider

provider aws prod_eu {
    region  = "eu-west-1"
    version = ">= 6.0.0"
}
The second bare identifier (prod_eu) is the alias. Aliases allow multiple instances of the same provider type to coexist. XCL identifiers use underscores, not hyphens — prod_eu not prod-eu.

Multiple providers

Same type, different regions

provider aws {
    region = "us-east-1"
}

provider aws prod_eu {
    region = "eu-west-1"
}
Both providers are in scope simultaneously. Resources with no provider meta-arg use the default (unaliased) provider implicitly at deploy time.

Multiple provider types

provider aws {
    region  = "us-east-1"
    version = ">= 6.0.0"
}

provider kubernetes {
    host = @cluster.endpoint
}

provider datadog {
    api_url = "https://api.datadoghq.eu"
}
Each provider type generates a separate import pulumi_<type> as <type> statement and pulumi-<type> entry in requirements.txt.

Per-resource routing

Use the provider meta-argument inside a resource body to direct that resource to a specific provider instance:
provider aws {
    region = "us-east-1"
}

provider aws prod_eu {
    region = "eu-west-1"
}

stack "multi-region" {
    // Uses the default (us-east-1) provider — no meta-arg needed.
    us_bucket = aws_s3_bucket {
        bucket = "assets-us"
    }

    // Explicitly routes to the prod_eu alias.
    eu_bucket = aws_s3_bucket {
        provider = aws.prod_eu
        bucket   = "assets-eu"
    }
}
provider = aws.prod_eu references the provider by name.alias. For the default (unaliased) provider use provider = aws. The provider meta-argument is accepted on:
  • name = TypePath { } resource declarations
  • name = module { } module calls
  • name = deploy helm|kustomize|manifest { } deploy declarations
  • name = sync argocd|flux { } sync declarations
  • name = data type { } data source bindings

version field

provider aws {
    version = ">= 6.0.0"
}
The version field accepts any semver constraint string. Recognized operators: >=, <=, >, <, !=, ==, ~>, ^, ~. Unrecognized formats produce a warning (not a hard error) — the program still compiles. The version is translated into a pip specifier in requirements.txt:
XCL versionrequirements.txt entry
>= 6.0.0pulumi-aws>=6.0.0
~> 6.1pulumi-aws~=6.1
< 7.0.0pulumi-aws<7.0.0
(absent)pulumi-aws>=1.0.0
When no version is present, the fallback >=1.0.0 is emitted.

Generated Python

Provider instantiation

provider aws {
    region = "us-east-1"
}
Generates a # ── Providers ── section before data bindings and resources:
# ── Providers ─────────────────────────────────────────────────────────────────
aws_provider = aws.Provider("aws",
    region="us-east-1",
)

Aliased provider

provider aws prod_eu {
    region = "eu-west-1"
}
Generates:
aws_prod_eu_provider = aws.Provider("prod_eu",
    region="eu-west-1",
)
The Python variable name is derived as {name}_provider or {name}_{alias}_provider.

Per-resource opts

eu_bucket = aws_s3_bucket {
    provider = aws.prod_eu
    bucket   = "assets-eu"
}
Generates:
eu_bucket = aws.s3.BucketV2("eu_bucket",
    bucket="assets-eu",
    opts=pulumi.ResourceOptions(provider=aws_prod_eu_provider),
)
opts=pulumi.ResourceOptions(provider=...) is appended after all regular properties.

Provider → Python package mapping

Provider typePython module aliaspip package
awsawspulumi-aws
kuberneteskubernetespulumi-kubernetes
datadogdatadogpulumi-datadog
gcpgcppulumi-gcp
azure / azure-nativeazure_nativepulumi-azure-native
(other){name}pulumi-{name}
The correct import pulumi_{name} as {name} statement is emitted even when no provider {} block is declared — imports are derived from resource type paths. A provider {} block adds the provider to the import list explicitly and enables version pinning.

Error conditions

Duplicate default provider

provider "aws" is declared more than once — use an alias for multiple instances: provider aws prod { ... }
Two provider aws { } blocks without aliases produce a hard compile error.

Duplicate alias

provider "aws" alias "prod_eu" is declared more than once
Two provider aws prod_eu { } blocks with the same name and alias produce a hard compile error.

Undeclared provider reference

provider "aws.missing" is not declared — add: provider aws { ... }
Using provider = aws.missing inside a resource body when no provider aws missing { } block exists is a hard compile error.

Invalid version format (warning only)

provider "aws" version ">= 6.0.0" may not be a valid semver constraint — expected e.g. ">= 6.0.0"
A version value that doesn’t start with a recognized operator or digit produces a warning. The program still compiles.

Scope rules

  • provider {} blocks are top-level — they live outside any stack {} and are visible to all stacks in the compilation unit
  • Two providers can have the same name if they have different aliases
  • Provider keys in scope are "aws" (default) and "aws.prod_eu" (aliased)
  • The provider = aws.prod_eu meta-argument is validated at compile time — the referenced provider must be declared