pulumi/pulumi-cloudflare

Import of Ruleset generates incorrect code when cache bypass enabled on rule

Closed this issue · 3 comments

Describe what happened

When importing a RulseSet from CloudFlare, if a cache rule is set to Bypass, the import will generate incorrect code missing the required property action_parameters, and show an incorrect update diff.

Repro:

Sample program

Create a ruleset with a single rule. Note "action_parameters": { "cache": False } on the rule.

"""A Python Pulumi program"""
import pulumi
import pulumi_cloudflare as cloudflare

config = pulumi.Config()
zone_id = config.require("zoneId")

website_staging_cache_rules = cloudflare.Ruleset("website-staging-cache-rules",
    kind="zone",
    name="default",
    phase="http_request_cache_settings",
    rules=[
        {
            "action": "set_cache_settings",
            "action_parameters": {
                "cache": False 
            },
            "description": "b-next.qa.b.io/*",
            "enabled": True,
            "expression": "http.host wildcard \"b-next.qa.b.io/*\"",
            "ref": "81058e3940c04aaf9acae2814691887f",
        },
    ],
    zone_id=zone_id)

pulumi.export("ruleset_id", website_staging_cache_rules.id)

After successfully creating the rule, delete the stack to abandon the ruleset:

pulumi stack rm dev --force

Create a new stack and import:

$ pulumi stack init dev
$ pulumi config env add shared/cloudflare # <- assume an ESC environment with `apiToken` `accountId` and `zoneId`
$ pulumi import cloudflare:index/ruleset:Ruleset website-staging-cache-rules zone/76a5f555962ec127742da23b908a44b4/8db37f899af842f285e60ef15deeca93

Outputs:

Do you want to perform this import? yes
Importing (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/initech/cloudflare-repro/dev/updates/1

     Type                         Name                         Status               
 +   pulumi:pulumi:Stack          cloudflare-repro-dev         created              
 =   └─ cloudflare:index:Ruleset  website-staging-cache-rules  imported (0.73s)     

Resources:
    + 1 created
    = 1 imported
    2 changes

Duration: 3s

Please copy the following code into your Pulumi application. Not doing so
will cause Pulumi to report that an update will happen on the next update command.

Please note that the imported resources are marked as protected. To destroy them
you will need to remove the `protect` option and run `pulumi update` *before*
the destroy will take effect.

import pulumi
import pulumi_cloudflare as cloudflare

website_staging_cache_rules = cloudflare.Ruleset("website-staging-cache-rules",
    kind="zone",
    name="default",
    phase="http_request_cache_settings",
    rules=[{
        "action": "set_cache_settings",
        "description": "b-next.qa.b.io/*",
        "enabled": True,
        "expression": "http.host wildcard \"b-next.qa.b.io/*\"",
        "ref": "81058e3940c04aaf9acae2814691887f",
    }],
    zone_id="76a5f555962ec127742da23b908a44b4",
    opts = pulumi.ResourceOptions(protect=True))

Note that the imported code is missing action_parameters copy this code into the main.py file and run:

pulumi preview --diff

❯ pulumi preview --diff
Previewing update (dev)

View Live: https://app.pulumi.com/initech/cloudflare-repro/dev/previews/2bbe046e-fc9a-4046-a2bf-b01470f9b4f2

  pulumi:pulumi:Stack: (same)
    [urn=urn:pulumi:dev::cloudflare-repro::pulumi:pulumi:Stack::cloudflare-repro-dev]
    ~ cloudflare:index/ruleset:Ruleset: (update) 🔒
        [id=8db37f899af842f285e60ef15deeca93]
        [urn=urn:pulumi:dev::cloudflare-repro::cloudflare:index/ruleset:Ruleset::website-staging-cache-rules]
        [provider=urn:pulumi:dev::cloudflare-repro::pulumi:providers:cloudflare::default_5_38_0::ae912c45-375a-4624-a997-3f5c7f872938]
        kind  : "zone"
        name  : "default"
        phase : "http_request_cache_settings"
        rules : [
            [0]: {
                action     : "set_cache_settings"
                description: "b-next.qa.b.io/*"
                enabled    : true
                expression : "http.host wildcard \"b-next.qa.b.io/*\""
                ref        : "81058e3940c04aaf9acae2814691887f"
            }
        ]
        zoneId: "76a5f555962ec127742da23b908a44b4"
    --outputs:--        
  + ruleset_id: "8db37f899af842f285e60ef15deeca93"
Resources:
    ~ 1 to update
    1 unchanged

This shows that Pulumi wants to update something, but there is no change in the diff.

Running pulumi up will result in an error:

❯ pulumi up --yes
Previewing update (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/initech/cloudflare-repro/dev/previews/f1e6af71-dd82-4eea-ae9b-a3752a1a9c3a

     Type                         Name                         Plan       
     pulumi:pulumi:Stack          cloudflare-repro-dev                    
 ~   └─ cloudflare:index:Ruleset  website-staging-cache-rules  update     

Outputs:
  + ruleset_id: "8db37f899af842f285e60ef15deeca93"

Resources:
    ~ 1 to update
    1 unchanged

Updating (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/initech/cloudflare-repro/dev/updates/2

     Type                         Name                         Status                  Info
     pulumi:pulumi:Stack          cloudflare-repro-dev         **failed**              1 error
 ~   └─ cloudflare:index:Ruleset  website-staging-cache-rules  **updating failed**     1 error

Diagnostics:
  pulumi:pulumi:Stack (cloudflare-repro-dev):
    error: update failed

  cloudflare:index:Ruleset (website-staging-cache-rules):
    error: error updating ruleset with ID "8db37f899af842f285e60ef15deeca93": action parameters are required for the set_cache_settings action (20106)

    [Pulumi Copilot] Would you like help with these diagnostics?
    https://app.pulumi.com/initech/cloudflare-repro/dev/updates/2?explainFailure

Resources:
    1 unchanged

Duration: 4s

Modification of the code to include "action_parameters": { "cache": False } will result in:

❯ pulumi preview --diff
Previewing update (dev)

View Live: https://app.pulumi.com/initech/cloudflare-repro/dev/previews/60196a82-f1d2-4dfe-aa3e-183736f8bea8

  pulumi:pulumi:Stack: (same)
    [urn=urn:pulumi:dev::cloudflare-repro::pulumi:pulumi:Stack::cloudflare-repro-dev]
    --outputs:--        
  + ruleset_id: "8db37f899af842f285e60ef15deeca93"
Resources:
    2 unchanged

Interestingly, modification of the code to include "action_parameters":{"cache":True} will result in:

❯ pulumi preview --diff
Previewing update (dev)

View Live: https://app.pulumi.com/initech/cloudflare-repro/dev/previews/3b7e2fa3-7047-4015-bd1a-df9eaedb4dc5

  pulumi:pulumi:Stack: (same)
    [urn=urn:pulumi:dev::cloudflare-repro::pulumi:pulumi:Stack::cloudflare-repro-dev]
    ~ cloudflare:index/ruleset:Ruleset: (update) 🔒
        [id=8db37f899af842f285e60ef15deeca93]
        [urn=urn:pulumi:dev::cloudflare-repro::cloudflare:index/ruleset:Ruleset::website-staging-cache-rules]
        [provider=urn:pulumi:dev::cloudflare-repro::pulumi:providers:cloudflare::default_5_38_0::ae912c45-375a-4624-a997-3f5c7f872938]
      ~ rules: [
          ~ [0]: {
                    action          : "set_cache_settings"
                  + actionParameters: {
                      + cache: true
                    }
                    description     : "b-next.qa.b.io/*"
                    enabled         : true
                    expression      : "http.host wildcard \"b-next.qa.b.io/*\""
                    ref             : "81058e3940c04aaf9acae2814691887f"
                }
        ]
    --outputs:--        
  + ruleset_id: "8db37f899af842f285e60ef15deeca93"
Resources:
    ~ 1 to update

Log output

No response

Affected Resource(s)

RuleSet

Output of pulumi about

❯ pulumi about
CLI
Version 3.134.1
Go Version go1.23.1
Go Compiler gc

Plugins
KIND NAME VERSION
resource aws 6.52.0
resource azure 5.43.0
resource cloudflare 5.38.0
resource kubernetes 4.18.1
resource pulumi_azuread 4.3.0
resource pulumi_terraform 5.13.4
language python unknown

Host
OS darwin
Version 15.1
Arch arm64

This project is written in python: executable='/Users/james/.pyenv/versions/3.11.6/bin/python3' version='3.11.6'

Current Stack: initech/cloudflare-repro/dev

TYPE URN
pulumi:pulumi:Stack urn:pulumi:dev::cloudflare-repro::pulumi:pulumi:Stack::cloudflare-repro-dev
pulumi:providers:cloudflare urn:pulumi:dev::cloudflare-repro::pulumi:providers:cloudflare::default_5_38_0
cloudflare:index/ruleset:Ruleset urn:pulumi:dev::cloudflare-repro::cloudflare:index/ruleset:Ruleset::website-staging-cache-rules

Found no pending operations associated with dev

Backend
Name pulumi.com
URL https://app.pulumi.com/automagic
User automagic
Organizations automagic, team-ce, initech, james-test, demo
Token type personal

Dependencies:
NAME VERSION
boto3 1.35.15
pip 24.2
pulumi_aws 6.52.0
pulumi_azure 5.43.0
pulumi_azuread 4.3.0
pulumi_cloudflare 5.38.0
pulumi_kubernetes 4.18.1
pulumi_terraform 5.13.4
setuptools 73.0.1
wheel 0.44.0

Pulumi locates its logs in /var/folders/b5/__9f51g104dbl435yq2tw8680000gn/T/ 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).

Thanks for reporting @automagic. This looks like a missing default value on the resource - guessing the API assumes the default value is there but the parameter is required. We could work around this by specifying the default on our side.

It looks like the upstream provider is distinguishing between cache = false and cache not being set. The bridge observes that cache = false is a zero value, and so doesn't present cache in the import view.

My plan to mitigate is to add a flag to the bridge's info.Schema to tell our import functions to not strip cache = false when set. That will be a surgical fix and address the immediate problem.

This issue has been addressed in PR #971 and shipped in release v5.43.1.