pulumi / pulumi-terraform-bridge

A library allowing Terraform providers to be bridged into Pulumi.
Apache License 2.0
192 stars 45 forks source link

Inserting an element in a list presents as multiple edits #2239

Open t0yv0 opened 1 month ago

t0yv0 commented 1 month ago

What happened?

Consider this program that inserts a new element into a TypeList property. When planning the change from step=0 to step=1, the user would expect Pulumi to display the planned change as an insertion at index 1. However, Pulumi does not recognize the insertion and instead projects multiple edits.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const config = new pulumi.Config();

const step = config.requireNumber("step");

const lt = new aws.ec2.LaunchTemplate("lt", {
    blockDeviceMappings: step === 0
    ? [
        {deviceName: "/dev/sda",
         ebs: {volumeSize: 20}},
        {deviceName: "/dev/sdf",
         ebs: {volumeSize: 30}},
    ] : [
        {deviceName: "/dev/sda",
         ebs: {volumeSize: 20}},
        {deviceName: "/dev/sdb",
         ebs: {volumeSize: 25}},
        {deviceName: "/dev/sdf",
         ebs: {volumeSize: 30}},
    ],
});

export const ltId = lt.id;

repro:

#!/usr/bin/env bash

set -euo pipefail

pulumi destroy --yes

pulumi config set step 0
pulumi up --skip-preview

pulumi config set step 1
pulumi preview --diff
pulumi up --skip-preview

The diff is displayed like this:

  pulumi:pulumi:Stack: (same)
    [urn=urn:pulumi:dev::pulumi-terraform-bridge-2234::pulumi:pulumi:Stack::pulumi-terraform-bridge-2234-dev]
    ~ aws:ec2/launchTemplate:LaunchTemplate: (update)
        [id=lt-030db90b79c0adb92]
        [urn=urn:pulumi:dev::pulumi-terraform-bridge-2234::aws:ec2/launchTemplate:LaunchTemplate::lt]
        [provider=urn:pulumi:dev::pulumi-terraform-bridge-2234::pulumi:providers:aws::default_6_45_0::e2444379-04b7-4ae1-8801-cf60ad99fc48]
      ~ blockDeviceMappings: [
          ~ [0]: {
                  + __defaults : []
                    deviceName : "/dev/sda"
                  ~ ebs        : {
                      + __defaults         : []
                      - deleteOnTermination: ""
                      - encrypted          : ""
                      - iops               : 0
                      - kmsKeyId           : ""
                      - snapshotId         : ""
                      - throughput         : 0
                        volumeSize         : 20
                      - volumeType         : ""
                    }
                  - noDevice   : ""
                  - virtualName: ""
                }
          ~ [1]: {
                  + __defaults : []
                  ~ deviceName : "/dev/sdf" => "/dev/sdb"
                  ~ ebs        : {
                      + __defaults         : []
                      - deleteOnTermination: ""
                      - encrypted          : ""
                      - iops               : 0
                      - kmsKeyId           : ""
                      - snapshotId         : ""
                      - throughput         : 0
                      ~ volumeSize         : 30 => 25
                      - volumeType         : ""
                    }
                  - noDevice   : ""
                  - virtualName: ""
                }
          + [2]: {
                  + deviceName: "/dev/sdf"
                  + ebs       : {
                      + volumeSize: 30
                    }
                }
        ]
Resources:              
    ~ 1 to update
    1 unchanged
Updating (dev)

Disregarding the empty/missing diff entries that are confusing, the diff still thinks that elements at index 1,2 were edited, instead of thinking of this change as a plain insertion/addition at index 1. This can be confusing especially for large collections.

Example

See above.

Output of pulumi about

CLI          
Version      3.124.0
Go Version   go1.22.5
Go Compiler  gc

Plugins
KIND      NAME    VERSION
resource  aws     6.45.0
resource  awsx    2.13.0
resource  docker  4.5.4
resource  docker  3.6.1
language  nodejs  unknown

Host     
OS       darwin
Version  14.5
Arch     arm64

This project is written in nodejs: executable='/Users/anton/bin/node' version='v18.18.2'

Current Stack: anton-pulumi-corp/pulumi-terraform-bridge-2234/dev

TYPE                                   URN
pulumi:pulumi:Stack                    urn:pulumi:dev::pulumi-terraform-bridge-2234::pulumi:pulumi:Stack::pulumi-terraform-bridge-2234-dev
pulumi:providers:aws                   urn:pulumi:dev::pulumi-terraform-bridge-2234::pulumi:providers:aws::default_6_45_0
aws:ec2/launchTemplate:LaunchTemplate  urn:pulumi:dev::pulumi-terraform-bridge-2234::aws:ec2/launchTemplate:LaunchTemplate::lt

Found no pending operations associated with dev

Backend        
Name           pulumi.com
URL            https://app.pulumi.com/anton-pulumi-corp
User           anton-pulumi-corp
Organizations  anton-pulumi-corp, moolumi, demo, pulumi
Token type     personal

Dependencies:
NAME            VERSION
typescript      5.5.4
@pulumi/aws     6.45.0
@pulumi/awsx    2.13.0
@pulumi/pulumi  3.126.0
@types/node     18.19.41

Pulumi locates its logs in /var/folders/gd/3ncjb1lj5ljgk8xl5ssn_gvc0000gn/T/com.apple.shortcuts.mac-helper// by default

Additional context

No response

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

t0yv0 commented 1 month ago

CC @VenelinMartinov another example of collection insertion diffs. To resolve we might need something like minimal edit distance detection https://github.com/t0yv0/godifft