Upgrading to Pulumi 3.0
Pulumi 3.0 is generally available. It’s simple to upgrade:
- Install or upgrade to the 3.0 CLI.
- Review the updated CLI behaviors listed below.
- Update each of your Pulumi programs to utilize the new version of the SDK.
Updated CLI behavior in Pulumi 3.0
Previously, when using the --stack
option on CLI commands, Pulumi would inconsistently set that stack as the current stack. In Pulumi 3.0, this behavior has now standardized and will NOT set the stack as the current stack. This affects the following commands:
pulumi cancel
pulumi config refresh
pulumi destroy
pulumi import
pulumi logs
pulumi preview
pulumi refresh
pulumi stack *
pulumi state
pulumi up
pulumi watch
Required updates to Pulumi programs
Update to the new SDK version
npm install @pulumi/pulumi@^3.0.0
Changes to pulumi.runtime.Mocks
The signature of the setMocks
function has changed with the introduction of the pulumi.runtime.MockResourceArgs
and pulumi.runtime.MockCallArgs
types. If you use setMocks
in your code, you’ll need to update to these new types.
// before
pulumi.runtime.setMocks({
newResource: function(type: string, name: string, inputs: any): {id: string, state: any} {
switch (type) {
case "aws:ec2/securityGroup:SecurityGroup":
return {
id: "sg-12345678",
state: {
...inputs,
arn: "arn:aws:ec2:us-west-2:123456789012:security-group/sg-12345678",
name: inputs.name || name + "-sg",
},
};
case "aws:ec2/instance:Instance":
return {
id: "i-1234567890abcdef0",
state: {
...inputs,
arn: "arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0",
instanceState: "running",
primaryNetworkInterfaceId: "eni-12345678",
privateDns: "ip-10-0-1-17.ec2.internal",
publicDns: "ec2-203-0-113-12.compute-1.amazonaws.com",
publicIp: "203.0.113.12",
},
};
default:
return {
id: inputs.name + "_id",
state: {
...inputs,
},
};
}
},
call: function(token: string, args: any, provider?: string) {
switch (token) {
case "aws:ec2/getAmi:getAmi":
return {
"architecture": "x86_64",
"id": "ami-0eb1f3cdeeb8eed2a",
};
default:
return args;
}
},
});
// after
pulumi.runtime.setMocks({
newResource: function(args: pulumi.runtime.MockResourceArgs): {id: string, state: any} {
switch (args.type) {
case "aws:ec2/securityGroup:SecurityGroup":
return {
id: "sg-12345678",
state: {
...args.inputs,
arn: "arn:aws:ec2:us-west-2:123456789012:security-group/sg-12345678",
name: args.inputs.name || name + "-sg",
},
};
case "aws:ec2/instance:Instance":
return {
id: "i-1234567890abcdef0",
state: {
...args.inputs,
arn: "arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0",
instanceState: "running",
primaryNetworkInterfaceId: "eni-12345678",
privateDns: "ip-10-0-1-17.ec2.internal",
publicDns: "ec2-203-0-113-12.compute-1.amazonaws.com",
publicIp: "203.0.113.12",
},
};
default:
return {
id: args.inputs.name + "_id",
state: {
...args.inputs,
},
};
}
},
call: function(args: MockCallArgs) {
switch (args.token) {
case "aws:ec2/getAmi:getAmi":
return {
"architecture": "x86_64",
"id": "ami-0eb1f3cdeeb8eed2a",
};
default:
return args.inputs;
}
},
});
Update to the new SDK version
Modify your requirements.txt
file to update the Pulumi SDK and any providers you use, like this:
pulumi>=3.0.0,<4.0.0
pulumi-aws>=4.0.0,<5.0.0
Then run pip install
:
pip install -r requirements.txt
Dictionary snake_case/camelCase Key Translation Fixes in Provider Python SDKs
Prior versions of Pulumi provider Python SDKs would unintentionally translate keys of user-defined dict
inputs (e.g. AWS tags
) from snake_case to camelCase (and vice versa for outputs) if the key happened to exist in the provider’s internal translation tables. Additionally, some provider SDKs did not consistently translate keys of nested data structures. All 3.0-based Pulumi provider Python SDKs have addressed these issues:
- Dictionary keys in user-defined
dict
s are no longer modified. - Dictionary keys in nested outputs are now consistently snake_case. If you’re accessing camelCase keys from such output classes, you need to update your code to access the values via the class’s snake_case property getters. A warning will be logged when accessing values from output classes using camelCase keys.
from pulumi import export
from pulumi_gcp import compute
instance = compute.Instance("instance", ...)
# before
export("ip", instance.network_interfaces[0]["accessConfigs"][0]["natIp"])
# after
export("ip", instance.network_interfaces[0].access_configs[0].nat_ip)
Changes to pulumi.runtime.Mocks
The signatures of the new_resource
and call
methods have changed with the introduction of the pulumi.runtime.MockResourceArgs
and pulumi.runtime.MockCallArgs
types. If you use new_resource
and call
in your code, you’ll need to update to these new types.
# before
class MyMocks(pulumi.runtime.Mocks):
def new_resource(self, token, name, inputs, provider, id_):
outputs = inputs
if token == "aws:ec2/instance:Instance":
outputs = {
**inputs,
"publicIp": "203.0.113.12",
"publicDns": "ec2-203-0-113-12.compute-1.amazonaws.com",
}
return [name + '_id', outputs]
def call(self, token, args, provider):
if token == "aws:ec2/getAmi:getAmi":
return {
"architecture": "x86_64",
"id": "ami-0eb1f3cdeeb8eed2a",
}
return {}
pulumi.runtime.set_mocks(MyMocks())
# after
class MyMocks(pulumi.runtime.Mocks):
def new_resource(self, args: pulumi.runtime.MockResourceArgs):
outputs = args.inputs
if args.token == "aws:ec2/instance:Instance":
outputs = {
**args.inputs,
"publicIp": "203.0.113.12",
"publicDns": "ec2-203-0-113-12.compute-1.amazonaws.com",
}
return [args.name + '_id', args.outputs]
def call(self, args: pulumi.runtime.MockCallArgs):
if args.token == "aws:ec2/getAmi:getAmi":
return {
"architecture": "x86_64",
"id": "ami-0eb1f3cdeeb8eed2a",
}
return {}
pulumi.runtime.set_mocks(MyMocks())
Update to the new SDK version
Modify your go.mod
file to update the Pulumi SDK and any providers you use, like this:
require (
github.com/pulumi/pulumi/sdk/v3 v3.0.0
github.com/pulumi/pulumi-aws/sdk/v4 v4.0.0
)
Then run go mod download
Remove any Apply<TypeName>
calls
In order to improve the performance of our Go SDK, we have removed:
Apply<TypeName>
Apply
ApplyWithContext
We now suggest that you use:
ApplyT
ApplyTWithContext
When using ApplyT, remember to cast the result to the Output type.
//before
containerDef := image.ImageName.ApplyString(func(name string) (string, error) {
return name, nil
})
//after
containerDef := image.ImageName.ApplyT(func(name string) (string, error) {
return name, nil
}).(pulumi.StringOutput)
Changes to pulumi.runtime.Mocks
The signatures of the NewResource
and Call
functions have changed with the introduction of the pulumi.runtime.MockResourceArgs
and pulumi.runtime.MockCallArgs
types. If you use setMocks
in your code, you’ll need to update to these new types.
//before
func (mocks) NewResource(token, name string, inputs resource.PropertyMap, provider, id string) (string, resource.PropertyMap, error) {
outputs := inputs.Mappable()
if token == "aws:ec2/instance:Instance" {
outputs["publicIp"] = "203.0.113.12"
outputs["publicDns"] = "ec2-203-0-113-12.compute-1.amazonaws.com"
}
return name + "_id", resource.NewPropertyMapFromMap(outputs), nil
}
func (mocks) Call(token string, args resource.PropertyMap, provider string) (resource.PropertyMap, error) {
outputs := map[string]interface{}{}
if token == "aws:ec2/getAmi:getAmi" {
outputs["architecture"] = "x86_64"
outputs["id"] = "ami-0eb1f3cdeeb8eed2a"
}
return resource.NewPropertyMapFromMap(outputs), nil
}
//after
func (mocks) NewResource(args pulumi.MockResourceArgs) (string, resource.PropertyMap, error) {
outputs := args.Inputs.Mappable()
if args.Token == "aws:ec2/instance:Instance" {
outputs["publicIp"] = "203.0.113.12"
outputs["publicDns"] = "ec2-203-0-113-12.compute-1.amazonaws.com"
}
return args.Name + "_id", resource.NewPropertyMapFromMap(outputs), nil
}
func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
outputs := map[string]interface{}{}
if args.Token == "aws:ec2/getAmi:getAmi" {
outputs["architecture"] = "x86_64"
outputs["id"] = "ami-0eb1f3cdeeb8eed2a"
}
return resource.NewPropertyMapFromMap(outputs), nil
}
Update to the new SDK version
Modify your project file to update the Pulumi SDK and any providers you use, like this:
<PackageReference Include="Pulumi" Version="3.0.*" />
Changes to pulumi.runtime.Mocks
The signatures of the NewResourceAsync
and CallAsync
methods have changed with the introduction of the pulumi.runtime.MockResourceArgs
and pulumi.runtime.MockCallArgs
types. If you use setMocks
in your code, you’ll need to update to these new types.
// before
public Task<(string id, object state)> NewResourceAsync(string type, string name, ImmutableDictionary<string, object> inputs, string? provider, string? id)
{
var outputs = ImmutableDictionary.CreateBuilder<string, object>();
// Forward all input parameters as resource outputs, so that we could test them.
outputs.AddRange(inputs);
if (type == "aws:ec2/instance:Instance")
{
outputs.Add("publicIp", "203.0.113.12");
outputs.Add("publicDns", "ec2-203-0-113-12.compute-1.amazonaws.com");
}
// Default the resource ID to `{name}_id`.
// We could also format it as `/subscription/abc/resourceGroups/xyz/...` if that was important for tests.
id ??= $"{name}_id";
return Task.FromResult((id, (object)outputs));
}
public Task<object> CallAsync(string token, ImmutableDictionary<string, object> inputs, string? provider)
{
var outputs = ImmutableDictionary.CreateBuilder<string, object>();
if (token == "aws:index/getAmi:getAmi")
{
outputs.Add("architecture", "x86_64");
outputs.Add("id", "ami-0eb1f3cdeeb8eed2a");
}
return Task.FromResult((object)outputs);
}
// after
public Task<(string id, object state)> NewResourceAsync(MockResourceArgs args)
{
var outputs = ImmutableDictionary.CreateBuilder<string, object>();
// Forward all input parameters as resource outputs, so that we could test them.
outputs.AddRange(args.Inputs);
if (args.Type == "aws:ec2/instance:Instance")
{
outputs.Add("publicIp", "203.0.113.12");
outputs.Add("publicDns", "ec2-203-0-113-12.compute-1.amazonaws.com");
}
// Default the resource ID to `{name}_id`.
// We could also format it as `/subscription/abc/resourceGroups/xyz/...` if that was important for tests.
id ??= $"{args.Name}_id";
return Task.FromResult((id, (object)outputs));
}
public Task<object> CallAsync(MockCallArgs args)
{
var outputs = ImmutableDictionary.CreateBuilder<string, object>();
if (args.Token == "aws:index/getAmi:getAmi")
{
outputs.Add("architecture", "x86_64");
outputs.Add("id", "ami-0eb1f3cdeeb8eed2a");
}
return Task.FromResult((object)outputs);
}
Required updates for automation API users
If you used a pre-GA release of Automation API, you need to update programs that use automation API to use the following namespaces:
// before
import as automation from "@pulumi/pulumi/x/automation";
//after
import as automation from "@pulumi/pulumi/automation";
#before
from pulumi.x import automation as auto
#after
from pulumi import automation as auto
//before
import (
"github.com/pulumi/pulumi/sdk/v2/go/pulumi"
"github.com/pulumi/pulumi/sdk/v2/go/x/auto"
"github.com/pulumi/pulumi/sdk/v2/go/x/auto/optdestroy"
"github.com/pulumi/pulumi/sdk/v2/go/x/auto/optup"
)
//after
import (
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/auto"
"github.com/pulumi/pulumi/sdk/v3/go/auto/optdestroy"
"github.com/pulumi/pulumi/sdk/v3/go/auto/optup"
)
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Pulumi.Automation;
Remaining on Pulumi 2.0
We recommend switching to Pulumi 3.0 if possible. We will only push critical security and bug fixes into the 2.x branch. Other fixes, feature enhancements, and new functionality will not be supported in the 2.x branch. In addition, provider updates will only be built against Pulumi 3.0.
If you wish to remain on the 2.x CLI, you can continue to download the CLI by referring to the manual installation instructions and choosing a specific version.
Running pulumi new
will attempt to use the latest versions of the project templates, which pull in the 3.0 SDK. You can continue to
use the 2.x templates by running pulumi new https://github.com/pulumi/templates/tree/2.x
.
Thank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.