CLI tool
pulumi/pulumi-aws avatar
pulumi/pulumi-aws

pulumi-aws, the AWS provider behind Pulumi programs

An Amazon Web Services (AWS) Pulumi resource package, providing multi-language access to AWS

579 stars195 forksGoApache-2.0

At a glance

What is it?
pulumi-aws is the Pulumi resource package for Amazon Web Services, generated from the Terraform AWS provider and published as SDKs for Node.js, Python, Go, .NET and more, so the same infrastructure can be written in several languages. It is a large generated codebase, and its release cadence is measured in minor version bumps every few days.
Who is it for?
pulumi-aws suits a team that has standardised on Pulumi and wants the full breadth of AWS resources with type-safe SDKs in the language they already write, and it suits teams that need to run the same infrastructure program from more than one language runtime.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A generated provider with a five-language SDK surface

pulumi-aws is described as an Amazon Web Services resource package providing multi-language access to AWS, and the top-level repository layout shows what that means in practice. There is a `provider/` directory for the provider binary itself, an `sdk/` directory for the generated language SDKs, an `upstream/` directory, `upstream-tools/`, `provider/`, `docs/`, `examples/`, `patches/`, `scripts/`, and a `Makefile` at the root.

The `upstream/` directory is the tell. This provider is generated from the Terraform AWS provider, and the Makefile makes that explicit: it sets `CODEGEN := pulumi-tfgen-aws` and `PROVIDER := pulumi-resource-aws`, and it injects a version string into `github.com/hashicorp/terraform-provider-aws/version.ProviderVersion` through linker flags. The version handling is careful, with a check that `PROVIDER_VERSION` does not start with a `v`, described as a common mistake, and a default of `7.0.0-alpha.0+dev` for local and branch builds that can be overridden in CI.

The SDKs are published to the standard package registries, and the badges show the npm package `@pulumi/aws`, the Python package `pulumi_aws`, the NuGet package `Pulumi.Aws` and a Go module path of `github.com/pulumi/pulumi-aws/sdk/v7/go`. The version path in the Makefile is `provider/v7`, so the major version is embedded in the module path, which is the Go convention for a v7 or later module and a signal that the package is expected to keep a stable import path across its major versions.

The licence is Apache-2.0, the last push to the repository was on 2026-10-20, and the recorded releases are v7.51.1 from 2026-10-16, v7.51.0 from 2026-10-15 and v7.50.0 from 2026-10-08. That cadence is the single most important operational fact about the package.

The audience is a team that has chosen Pulumi as its infrastructure-as-code layer and wants the whole of AWS available to it, in whatever language their programs are written in.The four install commands, one per language, are the whole setup for a consumer of the package.

bash
    $ npm install @pulumi/aws
    $ pip install pulumi_aws
    $ go get github.com/pulumi/pulumi-aws/sdk/v7
    $ dotnet add package Pulumi.Aws

The Go path is the one to note, because the major version is part of the module path. And the package itself does not install the Pulumi CLI; the documentation tells you to install the Pulumi CLI first, and the Get Started link covers the language runtime installation and the AWS configuration.

The resource surface is the whole of AWS

The concepts section is short, and it describes the design rather than the feature list.

The `@pulumi/aws` package provides a strongly-typed means to create cloud applications that create and interact closely with AWS resources. Resources are exposed for the entirety of AWS resources and their properties, including but not limited to apigateway, cloudformation, EC2, ECS, iam and lambda. Many convenience APIs have also been added to make development easier and to help avoid common mistakes, and to get stronger typing.

That last point is the one to take seriously. The generated resource surface is enormous, and the practical failure mode of a generated provider is that a resource has a property the type system accepts but the API rejects, or that a property was renamed upstream and the SDK lagged. The convenience layer exists precisely to put a hand-written, checked wrapper in front of the generated surface, so that the common operations are right even when the generated one is not.

The serverless function example shows what that means concretely. The `aws.lambda.CallbackFunction` class lets you create an AWS Lambda function directly out of a JavaScript or TypeScript function object of the right signature, so a Pulumi program can define a lambda in the language of its choice and let Pulumi do the transformation into the final AWS Lambda resource. The documentation notes this makes many APIs easier to use, such as defining a Lambda to execute when an S3 bucket is manipulated or a CloudWatch timer is fired, and points at the `examples/` directory for worked examples.

That is a well-chosen example to feature, because the raw generated shape for a Lambda is one of the more awkward in AWS, and a wrapper that takes a function object and produces the role, the archive and the permission is a real saving.

The breadth is also the cost. A package that covers the entirety of AWS in five languages is a large dependency, and the minor version bump every few days means your lockfile churns even when you changed nothing.

Configuration, and the options that decide how hard the provider fails

The configuration section is a long list of `aws:` keys, and most of them exist because the provider interacts with AWS in ways that can be wrong in confusing ways.

Only one is required. `aws:region` is the AWS region.

Credentials are handled in the familiar AWS ways, and every one of them has an environment variable fallback. `aws:accessKey` can be sourced from `AWS_ACCESS_KEY_ID`, and `aws:secretKey` from `AWS_SECRET_ACCESS_KEY`, both also readable from a shared credentials file when `aws:profile` is specified. `aws:profile` names the profile in the shared credentials file, and `aws:sharedCredentialsFiles` takes a list of paths, defaulting to `~/.aws/credentials` when a profile is used, with a single value also settable through `AWS_SHARED_CREDENTIALS_FILE`. `aws:token` covers the session token used after identity federation or an MFA login, and the documentation is careful to say it is the session token provided afterwards and not the six digit MFA code, and it can be sourced from `AWS_SESSION_TOKEN`.

The options that change behaviour under failure are the interesting ones. `aws:maxRetries` is the maximum number of times an API call is retried when requests are being throttled or experiencing transient failures, with the delay between subsequent calls increasing exponentially, and the default is `25`.

`aws:allowedAccountIds` and `aws:forbiddenAccountIds` are a safety pair, and they conflict with each other. They exist to prevent you from mistakenly using the wrong AWS account, which is the kind of mistake that is cheap to make and expensive to discover. The documentation frames both as preventing you from mistakenly using an incorrect one, with the forbidden list conflicting with the allowed list.

Two skip options are worth understanding because they are the difference between a provider that starts and one that refuses to start. `aws:skipCredentialsValidation` skips the credentials validation via the STS API, and it is useful for AWS API implementations that do not have STS available, with a default of `false` and an environment variable `AWS_SKIP_CREDENTIALS_VALIDATION`. `aws:skipRegionValidation` skips validation of the provided region name, useful for AWS-like implementations with their own region names or for regions not publicly available yet, and its default is `true`.

There is also `aws:insecure`, which explicitly allows the provider to perform insecure SSL requests and defaults to `false`, and `aws:endpoints` for customising service endpoints, which the documentation points at the Custom Service Endpoints Guide for connecting to alternate AWS endpoints or AWS-compatible solutions, with `aws:useFipsEndpoint` mentioned alongside.

`aws:assumeRole` is the largest of the options, taking a duration in seconds, an external ID, an IAM policy in JSON, a set of policy ARNs, a role ARN, a session name and a map of session tags. That is enough to express the common cross-account and restricted-permission patterns without writing a wrapper.

Running the generated provider from the Makefile

The Makefile is the best documentation of how this repository is actually built, and its first line warns that it is autogenerated and that changes will be overwritten when regenerated by the pulumi/ci-mgmt tooling.

That is worth understanding before you touch it. The file is produced by a central management repository, and the way to change the build without forking the generated file is the hook mechanism described in the header comment. The SDK codegen hooks make the Makefile include an optional provider-owned `sdk-hooks.mk`, and invoke `PRE_GEN_SDK_<LANG>` and `POST_GEN_SDK_<LANG>` slots around each per-language SDK codegen recipe. The file explains that ci-mgmt never creates `sdk-hooks.mk`, that it is opt-in, and points at `sdk-hooks.mk.example` in the pulumi/ci-mgmt repository for the contract and a worked example.

The build variables show the shape of the pipeline. `PROVIDER_PATH` is `provider/v7`, `VERSION_PATH` is `$(PROVIDER_PATH)/pkg/version.Version`, and the codegen binary and the provider binary are named `pulumi-tfgen-aws` and `pulumi-resource-aws`. `TESTPARALLELISM` is set to 10 and `TESTTAGS` defaults to `all`, so the test matrix is configurable per run.

The link flags show two things about the output. `LDFLAGS_STRIP_SYMBOLS=-s -w` strips debug information from the provider binary to reduce its size and speed up builds, and `LDFLAGS_PROJ_VERSION` sets both the provider's own version and the version of the upstream Terraform provider it was generated from, which the last flag pins to a literal `v`.

That last detail is the honest summary of the architecture. The provider is a bridge: Pulumi's own provider contract on one side, the Terraform AWS provider on the other, with a codegen step between them. The repository layout backs this up with `upstream/`, `upstream-tools/`, `patches/` and a `.schema-tools.version` file that pins the schema tooling, plus a `.upgrade-config.yaml` for the upstream merge process.

The repository also carries `AGENTS.md`, a `TESTING.md`, an `apm.yml` and `apm.lock.yaml` for dependency management, a `renovate.json5` for update automation, and a `devbox.json` with a `devbox.lock` for the development environment.

The release cadence is the operational cost

The recorded releases are v7.51.1 on 2026-10-16, v7.51.0 on 2026-10-15 and v7.50.0 on 2026-10-08. That is three minor releases in nine days, on a package that is versioned in the 7.x series and whose Go import path carries the major version.

For a consumer, the practical consequences are specific. A minor bump in the AWS provider is not a routine dependency bump, because the provider surface is generated from an upstream that moves when AWS ships a new service or a new property. The lockfile changes, the SDK packages are republished across five registries, and a provider upgrade can pull in behaviour changes to resources you did not touch.

The Makefile's own version handling shows the care taken here. The default `PROVIDER_VERSION` for local and branch builds is `7.0.0-alpha.0+dev`, and the comment explains that a version can be overridden in CI using a make target argument or an environment variable, so branch builds and release builds can carry different version strings deliberately.

The interesting question for an adopter is not whether this project is well maintained, because a daily release line says it is, but whether your team can absorb a provider that moves that fast. If you pin the SDK packages and let the provider version move independently, you are insulated from most of it. If you regenerate your lockfile whenever anything changes, you are not.

There is also a version boundary worth knowing about. The Go module path is `github.com/pulumi/pulumi-aws/sdk/v7/go` and the provider path is `provider/v7`, so a major version bump changes the import path and requires a code change in every Go program that imports it. That is the Go convention doing its job, and it is also a reminder that the 7.x line is a long commitment.

For a team already running Pulumi, none of this is a reason to avoid the provider. It is a reason to pin.

When this is the wrong provider for the job

The case for pulumi-aws is strong when you have already chosen Pulumi and want the full breadth of AWS in your language of choice. The case against is about size and churn, and there are three concrete situations where a different approach fits better.

First, if you do not want a provider dependency at all. The provider binary is a separate process that Pulumi launches, it authenticates, it validates, and it talks to the AWS APIs. For a small account with a handful of resources, the AWS Cloud Control API or a short script using the AWS SDK directly is smaller and easier to reason about. The cost of that choice is that you hand-write the dependency ordering and the drift handling that Pulumi would have given you.

Second, if your infrastructure is mostly Kubernetes or another platform rather than AWS. The provider is a large surface, and most of it will be unused.

Third, if the upstream generation model itself is the problem. Because the provider is derived from the Terraform AWS provider, a resource that Terraform models in a particular way is inherited by Pulumi, including the awkward parts. If your requirement is that the Pulumi resource model is the canonical one, this is not the package that gives you that.

The alternative in the Pulumi ecosystem is a different provider, or a different tool entirely. A provider built by hand for a narrow slice of AWS, or a Terraform configuration managed by OpenTofu with the same state-file discipline, follows a different approach: the first gives you exactly the model you want at the cost of writing and maintaining the mapping, and the second gives you the maturity of the upstream ecosystem at the cost of giving up the multi-language SDK story and Pulumi's state model.

The deciding question is usually about how many resources and how many teams. One team and ten resources, take the smaller path. Several teams and several hundred resources, the generated provider's consistency is worth its size.

Editorial conclusion

pulumi-aws suits a team that has standardised on Pulumi and wants the full breadth of AWS resources with type-safe SDKs in the language they already write, and it suits teams that need to run the same infrastructure program from more than one language runtime. It does not suit a team that wants a small, stable dependency, because the package covers the entirety of AWS and is versioned on a rapid minor cadence, and it does not suit a team that wants to hand-edit provider internals, since the code is generated. Verify first that the AWS resources you need are exposed by the version you pin, that your language runtime has a published SDK for it, and that the configuration defaults for retries, region validation and credential checks match how your organisation expects the provider to behave.

Frequently asked questions

How do I install the Pulumi AWS provider for my language?

The packages are published for each language. For Node.js or TypeScript, npm install @pulumi/aws or yarn add @pulumi/aws. For Python, pip install pulumi_aws. For Go, go get github.com/pulumi/pulumi-aws/sdk/v7. For .NET, dotnet add package Pulumi.Aws.

Which AWS resources does the Pulumi AWS provider expose?

Resources are exposed for the entirety of AWS resources and their properties, including apigateway, cloudformation, EC2, ECS, iam and lambda. Convenience APIs sit on top of that generated surface to avoid common mistakes and to give stronger typing.

What configuration options does pulumi-aws accept for credentials?

The access key, secret key and session token can each be set through configuration or read from the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN environment variables, or from a shared credentials file named by aws:profile or the paths in aws:sharedCredentialsFiles.

How often does the Pulumi AWS provider release new versions?

The recorded releases are v7.51.1 from 2026-10-16, v7.51.0 from 2026-10-15 and v7.50.0 from 2026-10-08, so minor versions land every few days. The provider is generated from the upstream Terraform AWS provider, which is why the surface changes that often.

Can I customise the build of the Pulumi AWS provider?

Yes, without forking the generated Makefile. The Makefile includes an optional provider-owned sdk-hooks.mk and invokes PRE_GEN_SDK and POST_GEN_SDK slots around each per-language SDK codegen recipe. The file is autogenerated by the pulumi/ci-mgmt tooling, and sdk-hooks.mk.example in that repository documents the contract.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. pulumi/pulumi-aws on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pulumi-pulumi-aws.svg)](https://hysenlabs.com/projects/pulumi-pulumi-aws)

Was this useful?