@@ -17,15 +17,15 @@ social:
17
17
Pulumi now supports executing Terraform modules directly! No more complex conversions for module-heavy projects. Migrate from Terraform to Pulumi with ease.
18
18
linkedin : |
19
19
We're excited to announce that Pulumi can now execute Terraform modules directly, addressing one of the biggest challenges in migrating complex infrastructure from Terraform to Pulumi.
20
-
20
+
21
21
This new capability eliminates the need to convert module sources, allowing teams to immediately manage everything with Pulumi while maintaining the exact Terraform semantics they're familiar with.
22
-
22
+
23
23
Key benefits:
24
24
• Seamless migration for module-heavy projects
25
25
• Type-safe integration with Pulumi programming languages
26
26
• Automatic state management in Pulumi Cloud
27
27
• Full support for Terraform and OpenTofu registries
28
-
28
+
29
29
This represents a significant step forward in making infrastructure migration accessible to teams of all sizes.
30
30
---
31
31
@@ -86,26 +86,82 @@ Pulumi providers now expose helper methods like `awsProvider.terraformConfig()`
86
86
87
87
Let me walk you through a practical example that demonstrates the power of this integration.
88
88
89
- First, [ install the latest version of the Pulumi CLI] ( /docs/install/ ) (v3.178.0 or later is required) and create a new Pulumi TypeScript project using ` pulumi new typescript ` .
89
+ First, [ install the latest version of the Pulumi CLI] ( /docs/install/ ) (v3.178.0 or later is required) and create a new Pulumi project using ` pulumi new $language ` such as ` pulumi new typescript ` .
90
90
91
91
### Setting Up a VPC Module
92
92
93
93
Next, add a Terraform module to your Pulumi project:
94
94
95
+ {{% chooser language "typescript,python,go" %}}
96
+
97
+ {{% choosable language typescript %}}
98
+
95
99
``` bash
96
- $ pulumi package add terraform-module terraform-aws-modules/vpc/aws 6.0.1 vpcmod
100
+ $ pulumi package add terraform-module terraform-aws-modules/vpc/aws 6.0.0 vpcmod
97
101
Successfully generated a Nodejs SDK for the vpcmod package at /Users/anton/tmp/2025-06-23/blog/sdks/vpcmod
98
102
```
99
103
100
- Pulumi automatically generates a local SDK with full TypeScript support:
104
+ {{% /choosable %}}
105
+
106
+ {{% choosable language python %}}
107
+
108
+ ``` bash
109
+ $ pulumi package add terraform-module terraform-aws-modules/vpc/aws 6.0.0 vpcmod
110
+
111
+ Successfully generated a Python SDK for the vpcmod package at /workdir/vpcmod
112
+
113
+ Resolved 13 packages in 111ms
114
+ Built pulumi-vpcmod @ file:///workdir/sdks/vpcmod
115
+ Prepared 4 packages in 297ms
116
+ Installed 4 packages in 1ms
117
+ + arpeggio==2.0.2
118
+ + attrs==25.3.0
119
+ + parver==0.5
120
+ + pulumi-vpcmod==6.0.0 (from file:///workdir/sdks/vpcmod)
121
+
122
+ You can then import the SDK in your Python code with:
123
+
124
+ import pulumi_vpcmod as vpcmod
125
+ ```
126
+
127
+ {{% /choosable %}}
128
+
129
+ {{% choosable language go %}}
130
+ Using Terraform CLI for schema inference
131
+ Successfully generated a Go SDK for the vpcmod package at /workdir/sdks/vpcmod
132
+ Go mod file updated to use local sdk for vpcmod
133
+ To use this package, import github.com/pulumi/pulumi-terraform-module/sdks/go/vpcmod/v6/vpcmod
134
+ Added package "vpcmod" to Pulumi.yaml
135
+ {{% /choosable %}}
136
+
137
+ {{% /chooser %}}
138
+
139
+ Pulumi automatically generates a local SDK with full support for your language:
140
+
141
+ {{% chooser language "typescript,python,go" %}}
142
+
143
+ {{% choosable language typescript %}}
101
144
102
145
``` bash
103
146
$ ls sdks/vpcmod
104
147
README.md index.ts node_modules provider.ts tsconfig.json utilities.ts
105
148
bin module.ts package.json scripts types
106
149
```
150
+ {{% /choosable %}}
107
151
108
- And links it into your project in ` package.json ` :
152
+ {{% choosable language python %}}
153
+ $ ls sdks/vpcmod
154
+ build pulumi_vpcmod pulumi_vpcmod.egg-info setup.py
155
+ {{% /choosable %}}
156
+
157
+ {{% choosable language go %}}
158
+ $ ls sdks/vpcmod
159
+ go.mod vpcmod
160
+ {{% /choosable %}}
161
+
162
+ {{% /chooser %}}
163
+
164
+ And links it into your project such as ` package.json ` when using TypeScript:
109
165
110
166
``` json
111
167
{
@@ -119,6 +175,9 @@ And links it into your project in `package.json`:
119
175
120
176
Now you can use the module with full IntelliSense support:
121
177
178
+ {{% chooser language "typescript,python,go" %}}
179
+
180
+ {{% choosable language typescript %}}
122
181
``` typescript
123
182
import * as pulumi from " @pulumi/pulumi" ;
124
183
import * as vpcmod from ' @pulumi/vpcmod' ;
@@ -142,6 +201,86 @@ const vpc = new vpcmod.Module("test-vpc", {
142
201
export const publicSubnets = vpc .public_subnets ;
143
202
export const privateSubnets = vpc .private_subnets ;
144
203
```
204
+ {{% /choosable %}}
205
+
206
+ {{% choosable language python %}}
207
+ ``` python
208
+ import * as pulumi from " @pulumi/pulumi" ;
209
+ import * as vpcmod from ' @pulumi/vpcmod' ;
210
+
211
+ const vpc = new vpcmod.Module(" test-vpc" , {
212
+ azs: [" us-west-2a" , " us-west-2b" ],
213
+ name: `test- vpc- $ {pulumi.getStack()}` ,
214
+ cidr: " 10.0.0.0/16" ,
215
+ public_subnets: [
216
+ " 10.0.1.0/24" ,
217
+ " 10.0.2.0/24" ,
218
+ ],
219
+ private_subnets: [
220
+ " 10.0.3.0/24" ,
221
+ " 10.0.4.0/24" ,
222
+ ],
223
+ enable_nat_gateway: true,
224
+ single_nat_gateway: true,
225
+ });
226
+
227
+ export const publicSubnets = vpc.public_subnets;
228
+ export const privateSubnets = vpc.private_subnets;
229
+ ```
230
+ {{% /choosable %}}
231
+
232
+ {{% choosable language go %}}
233
+
234
+ ``` go
235
+ package main
236
+
237
+ import (
238
+ " fmt"
239
+
240
+ " github.com/pulumi/pulumi-terraform-module/sdks/go/vpcmod/v6/vpcmod"
241
+ " github.com/pulumi/pulumi/sdk/v3/go/pulumi"
242
+ )
243
+
244
+ func run (ctx *pulumi .Context ) error {
245
+ stack := ctx.Stack ()
246
+
247
+ vpc , err := vpcmod.NewModule (ctx, " test-vpc" , &vpcmod.ModuleArgs {
248
+ Azs: pulumi.StringArray {
249
+ pulumi.String (" us-west-2a" ),
250
+ pulumi.String (" us-west-2b" ),
251
+ },
252
+ Name: pulumi.String (fmt.Sprintf (" test-vpc-%s " , stack)),
253
+ Cidr: pulumi.String (" 10.0.0.0/16" ),
254
+ Public_subnets: pulumi.StringArray {
255
+ pulumi.String (" 10.0.1.0/24" ),
256
+ pulumi.String (" 10.0.2.0/24" ),
257
+ },
258
+ Private_subnets: pulumi.StringArray {
259
+ pulumi.String (" 10.0.3.0/24" ),
260
+ pulumi.String (" 10.0.4.0/24" ),
261
+ },
262
+ Enable_nat_gateway: pulumi.Bool (true ),
263
+ Single_nat_gateway: pulumi.Bool (true ),
264
+ })
265
+ if err != nil {
266
+ return err
267
+ }
268
+
269
+ ctx.Export (" publicSubnets" , vpc.Public_subnets )
270
+ ctx.Export (" privateSubnets" , vpc.Private_subnets )
271
+
272
+ return nil
273
+ }
274
+
275
+ func main () {
276
+ pulumi.Run (run)
277
+ }
278
+ ```
279
+
280
+ {{% /choosable %}}
281
+
282
+ {{% /chooser %}}
283
+
145
284
146
285
### Seamless Deployment
147
286
@@ -189,7 +328,7 @@ For teams starting with existing Terraform code, the migration process is straig
189
328
// @pulumi-terraform-module vpcmod
190
329
module "my-vpc" {
191
330
source = "terraform-aws-modules/vpc/aws"
192
- version = "6.0.1 "
331
+ version = "6.0.0 "
193
332
azs = ["us-west-2a", "us-west-2b"]
194
333
name = "test-vpc-123"
195
334
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
@@ -199,7 +338,7 @@ module "my-vpc" {
199
338
}
200
339
```
201
340
202
- Then run the conversion:
341
+ Then run the conversion (replace ` typescript ` with your language of choice) :
203
342
204
343
``` bash
205
344
pulumi convert --from terraform --language typescript --out my-pulumi-project
@@ -211,9 +350,13 @@ The resulting project is ready to deploy with full Pulumi functionality.
211
350
212
351
One of the key benefits is seamless configuration management. Instead of maintaining separate configurations for Pulumi and Terraform providers, you can reuse your existing Pulumi provider configuration:
213
352
353
+ {{% chooser language "typescript,python,go" %}}
354
+
355
+ {{% choosable language typescript %}}
356
+
214
357
``` typescript
215
358
const awsProvider = new aws .Provider (" awsprovider" , {
216
- region: " us-east-1 " ,
359
+ region: " us-west-2 " ,
217
360
// more configuration
218
361
});
219
362
@@ -228,6 +371,69 @@ const vpc = new vpcmod.Module("test-vpc", {...},
228
371
);
229
372
```
230
373
374
+ {{% /choosable %}}
375
+
376
+ {{% choosable language python %}}
377
+
378
+ ``` python
379
+ import pulumi
380
+ import pulumi_aws as aws
381
+ import pulumi_vpcmod as vpcmod
382
+
383
+ aws_provider = aws.Provider(" awsprovider" , region = " us-west-2" )
384
+
385
+ # Pass the AWS configuration to your VPC module provider
386
+ vpcmod_provider = vpcmod.Provider(" vpcprovider" , aws = aws_provider.terraform_config().result)
387
+
388
+ # Use the VPC module provider in your Module
389
+ vpc = vpcmod.Module(" test-vpc" , ... , opts = pulumi.ResourceOptions(provider = vpcmod_provider))
390
+ ```
391
+
392
+ {{% /choosable %}}
393
+
394
+ {{% choosable language go %}}
395
+
396
+ ``` go
397
+ func run (ctx *pulumi .Context ) error {
398
+ stack := ctx.Stack ()
399
+
400
+ awsProvider , err := aws.NewProvider (ctx, " awsprovider" , &aws.ProviderArgs {
401
+ Region: pulumi.String (" us-west-2" ),
402
+ })
403
+ if err != nil {
404
+ return err
405
+ }
406
+
407
+ awsProviderTfConfig , err := awsProvider.TerraformConfig (ctx)
408
+ if err != nil {
409
+ return err
410
+ }
411
+
412
+ // Pass the AWS configuration to your VPC module provider
413
+ vpcProvider , err := vpcmod.NewProvider (ctx, " vpcprovider" , &vpcmod.ProviderArgs {
414
+ Aws: awsProviderTfConfig.Result (),
415
+ })
416
+ if err != nil {
417
+ return err
418
+ }
419
+
420
+ // Use the VPC module provider in your Module
421
+ vpc , err := vpcmod.NewModule (ctx, " test-vpc" , &vpcmod.ModuleArgs {...}, pulumi.Provider (vpcProvider))
422
+ if err != nil {
423
+ return err
424
+ }
425
+
426
+ ctx.Export (" publicSubnets" , vpc.Public_subnets )
427
+ ctx.Export (" privateSubnets" , vpc.Private_subnets )
428
+
429
+ return nil
430
+ }
431
+ ```
432
+
433
+ {{% /choosable %}}
434
+
435
+ {{% /chooser %}}
436
+
231
437
This demonstrates how Terraform modules integrate seamlessly with existing Pulumi programs, allowing you to compose infrastructure components naturally.
232
438
233
439
## What's Supported
0 commit comments