OctopusDeployLabs / terraform-provider-octopusdeploy

Terraform Provider for Octopus Deploy :octopus:
https://registry.terraform.io/providers/OctopusDeployLabs/octopusdeploy
Mozilla Public License 2.0
82 stars 67 forks source link

Step actions with multiple packages re-added on each Plan/Apply #140

Open danriggs opened 3 years ago

danriggs commented 3 years ago

Describe the bug Similar to #133, when adding multiple package blocks to a deployment process step action they are evaluated as items that need to be updated on each run of terraform.

Steps to reproduce Apply Terraform Run Terraform Plan Review Output (none is expected since the system was just updated)

Fully contained main.tf below:

terraform {
  required_providers {
    octopusdeploy = {
      source = "OctopusDeployLabs/octopusdeploy"
    }
  }
}

provider "octopusdeploy" {
  address  = "https://XXXXXXXXX"
  api_key  = "API-XXXXXXX"
  space_id = "Spaces-1"
}

resource "octopusdeploy_project_group" "testing" {
  name        = "Testing"
  description = ""
}

resource "octopusdeploy_environment" "testing" {
  name = "Testing"
}

resource "octopusdeploy_lifecycle" "testing" {
  name = "Testing"

  phase {
    is_optional_phase                     = false
    minimum_environments_before_promotion = 0
    name                                  = "Any environment"
    optional_deployment_targets           = []
  }

  release_retention_policy {
    quantity_to_keep    = 1
    should_keep_forever = false
    unit                = "Items"
  }

  tentacle_retention_policy {
    quantity_to_keep    = 1
    should_keep_forever = false
    unit                = "Items"
  }
}

resource "octopusdeploy_nuget_feed" "testing" {
  name     = "testing"
  feed_uri = "http://testfeed.com"
}

resource "octopusdeploy_project" "testing" {
  name             = "git-project-test"
  lifecycle_id     = octopusdeploy_lifecycle.testing.id
  project_group_id = octopusdeploy_project_group.testing.id
}

resource "octopusdeploy_deployment_process" "testing" {

  project_id = octopusdeploy_project.testing.id

  step {
    condition           = "Success"
    name                = "Package Example"
    package_requirement = "LetOctopusDecide"
    start_trigger       = "StartAfterPrevious"
    properties = {
      "Octopus.Action.TargetRoles" = "role1,role2"
    }
    target_roles = [
      "role1",
      "role2"
    ]

    action {
      action_type                        = "Octopus.Script"
      can_be_used_for_project_versioning = true
      is_disabled                        = false
      is_required                        = false
      name                               = "Package Example"
      run_on_server                      = false
      properties = {
        "Octopus.Action.Package.DownloadOnTentacle" = "False"
        "Octopus.Action.Package.FeedId"             = octopusdeploy_nuget_feed.testing.id
        "Octopus.Action.Package.PackageId"          = "package1"
        "Octopus.Action.RunOnServer"                = "false"
        "Octopus.Action.Script.ScriptFileName"      = "package1.ps1"
        "Octopus.Action.Script.ScriptSource"        = "Package"
      }

      primary_package {
        acquisition_location = "Server"
        feed_id              = octopusdeploy_nuget_feed.testing.id
        package_id           = "package1"
      }
      package {
        acquisition_location      = "Server"
        feed_id                   = octopusdeploy_nuget_feed.testing.id
        name                      = "package2"
        package_id                = "package2"
        extract_during_deployment = false
        properties = {
          "Extract" = "False"
        }
      }
    }
  }
}

Expected behavior I expect there not to be any output and to report back Infrastructure up to date.

Logs and other supporting information Terraform plan:

  ~ resource "octopusdeploy_deployment_process" "testing" {
        id         = "deploymentprocess-Projects-23"
        # (3 unchanged attributes hidden)

      ~ step {
            id                  = "e9629a7a-cf84-4c61-9e37-b69c42542531"
            name                = "Package Example"
          ~ target_roles        = [
              + "role1",
              + "role2",
            ]
            # (4 unchanged attributes hidden)

          ~ action {
                id                                 = "dcbe5108-8f33-483e-ada6-8a07e1d0c66b"
                name                               = "Package Example"
                # (11 unchanged attributes hidden)

              - package {
                  - acquisition_location      = "Server" -> null
                  - extract_during_deployment = false -> null
                  - feed_id                   = "Feeds-1051" -> null
                  - id                        = "0c1e9073-8d67-4c8c-afbd-fe8e8ecb26d1" -> null
                  - package_id                = "package1" -> null
                  - properties                = {} -> null
                }
              - package {
                  - acquisition_location      = "Server" -> null
                  - extract_during_deployment = false -> null
                  - feed_id                   = "Feeds-1051" -> null
                  - id                        = "c9fd8222-b03d-4785-b261-d977e9ffa06b" -> null
                  - name                      = "package2" -> null
                  - package_id                = "package2" -> null
                  - properties                = {
                      - "Extract" = "false"
                    } -> null
                }
              + package {
                  + acquisition_location      = "Server"
                  + extract_during_deployment = false
                  + feed_id                   = "Feeds-1051"
                  + id                        = (known after apply)
                  + name                      = "package2"
                  + package_id                = "package2"
                  + properties                = {
                      + "Extract" = "False"
                    }
                }

              + primary_package {
                  + acquisition_location = "Server"
                  + feed_id              = "Feeds-1051"
                  + id                   = (known after apply)
                  + package_id           = "package1"
                }
                # (1 unchanged block hidden)
            }
        }
    }

Environment and versions:

Additional context Add any other context about the problem here.

ryoldash commented 3 years ago

I faced the same issue. Recently I updated Octopusdeploy provider to 0.7.10 and when I got this issue I tried 0.7.11, 0.7.12 and 0.7.13 as well. I googled but couldn't find any suggestion in this regard. When I compared the state file with the previous version of octopusdeploy provider I noticed that the new version inserts the "action" block to "run_script_action" block in the state file. And when we run the terraform apply for the second time since tfstate points to the empty "action" block it throws error. I added the section from tfstate. As seen in the tfstate's code block "action" block is empty and all "action" block's definitions are moved to "run_script_action".

@jbristowe Since I was facing the same issue on my project I tried @danriggs example and I got same error.

"step": [
  {
    "action": [],
    "apply_terraform_action": [],
    "condition": "Success",
    "condition_expression": "",
    "deploy_kubernetes_secret_action": [],
    "deploy_package_action": [],
    "deploy_windows_service_action": [],
    "id": "id",
    "manual_intervention_action": [],
    "name": "Package Example",
    "package_requirement": "LetOctopusDecide",
    "properties": {
      "Octopus.Action.TargetRoles": "role1,role2"
    },
    "run_kubectl_script_action": [],
    "run_script_action": [
      {
        "can_be_used_for_project_versioning": true,
        "channels": [],
        "condition": "Success",
        "container": [
          {
            "feed_id": "",
            "image": ""
          }
        ],
        "environments": [],
        "excluded_environments": [],
        "id": "id",
        "is_disabled": false,
        "is_required": false,
        "name": "Package Example",
        "notes": "",
        "package": [
          {
            "acquisition_location": "Server",
            "extract_during_deployment": false,
            "feed_id": "Feeds-id",
            "id": "id",
            "name": "package2",
            "package_id": "package2",
            "properties": {
              "Extract": "False"
            }
          }
        ],
        "primary_package": [
          {
            "acquisition_location": "Server",
            "feed_id": "Feeds-id",
            "id": "id",
            "name": "",
            "package_id": "package1",
            "properties": {}
          }
        ],
        "properties": {
          "Octopus.Action.Package.DownloadOnTentacle": "False",
          "Octopus.Action.Package.FeedId": "Feeds-id",
          "Octopus.Action.Package.PackageId": "package1",
          "Octopus.Action.RunOnServer": "false",
          "Octopus.Action.Script.ScriptFileName": "package1.ps1",
          "Octopus.Action.Script.ScriptSource": "Package"
        },
        "run_on_server": false,
        "script_file_name": "package1.ps1",
        "script_parameters": "",
        "script_source": "Package",
        "tenant_tags": [],
        "variable_substitution_in_files": ""
      }
    ],
    "start_trigger": "StartAfterPrevious",
    "target_roles": [
      "role1",
      "role2"
    ],
    "window_size": ""
  }

When I downloaded the JSON from UI the "action" was in the right place.

"Steps": [
  {
    "Id": "id",
    "Name": "Package Example",
    "PackageRequirement": "LetOctopusDecide",
    "Properties": {
      "Octopus.Action.TargetRoles": "role1,role2"
    },
    "Condition": "Success",
    "StartTrigger": "StartAfterPrevious",
    "Actions": [
      {
        "Id": "id",
        "Name": "Package Example",
        "ActionType": "Octopus.Script",
        "Notes": null,
        "IsDisabled": false,
        "CanBeUsedForProjectVersioning": true,
        "IsRequired": false,
        "WorkerPoolId": null,
        "Container": {
          "Image": null,
          "FeedId": null
        },
        "WorkerPoolVariable": null,
        "Environments": [],
        "ExcludedEnvironments": [],
        "Channels": [],
        "TenantTags": [],
        "Packages": [
          {
            "Name": "",
            "Id": "id",
            "PackageId": "package1",
            "FeedId": "Feeds-id",
            "AcquisitionLocation": "Server",
            "Properties": {}
          },
          {
            "Name": "package2",
            "Id": "id",
            "PackageId": "package2",
            "FeedId": "Feeds-id",
            "AcquisitionLocation": "Server",
            "Properties": {
              "Extract": "False"
            }
          }
        ],
        "Condition": "Success",
        "Properties": {
          "Octopus.Action.Package.DownloadOnTentacle": "False",
          "Octopus.Action.Package.FeedId": "Feeds-id",
          "Octopus.Action.Package.PackageId": "package1",
          "Octopus.Action.RunOnServer": "false",
          "Octopus.Action.Script.ScriptFileName": "package1.ps1",
          "Octopus.Action.Script.ScriptSource": "Package"
        },
        "Links": {}
      }
    ]
  }
],

I hope this issue would be fixed soon.

jbristowe commented 3 years ago

The next release of the provider will fix this issue.

The generic action will likely be deprecated and removed in a future release of the provider. We have added specific actions like run_script_action, which provide import support and better validation. This also applies to the properties collection; it will likely be deprecated and removed in a future release.

pemaxim commented 3 years ago

Hi @jbristowe. Is there any update on it? Also, just wanted to add that run_script_action does not support worker_pool_id attribute, which is the problem too.

DamienDaco commented 3 years ago

Hi @jbristowe , FYI , the example in https://registry.terraform.io/providers/OctopusDeployLabs/octopusdeploy/latest/docs/resources/deployment_process#nested-schema-for-steprun_script_action still uses the generic 'action' , which lead me to this problem . Regards