terraform-provider-octopusdeploy icon indicating copy to clipboard operation
terraform-provider-octopusdeploy copied to clipboard

Order of actions within a deployment process step is not respected when different types of action are in use

Open borland opened this issue 3 years ago • 0 comments

Note This only applies to cases where there are multiple actions within the same step. The common case is for steps to contain a single action, many configurations are unlikely to be affected by this bug.

Steps to reproduce

The following terraform file (psuedocode, some elements removed, garbage example data) should reproduce the problem

resource "octopusdeploy_deployment_process" "my_deployment_process" {
  project_id  = octopusdeploy_project.my_project.id
  step {
    condition           = "Success"
    name                = "Deploy Website"
    run_script_action {
      name        = "script1"
      script_body = <<-EOT
          Write-Host 'Checking Server'
        EOT
    }
    action {
      name          = "action1"
      action_type   = "Octopus.IIS"
      run_on_server = true

      properties = {
        "Octopus.Action.IISWebSite.DeploymentType": "webSite",
        "Octopus.Action.IISWebSite.StartWebSite": "True",
        ...
      }
    }
    run_script_action {
      name        = "script2"
      script_body = <<-EOT
          Write-Host 'Verifying Server'
        EOT
    }
    action {
      name          = "action2"
      action_type   = "Octopus.IIS"
      run_on_server = true

      properties = {
        "Octopus.Action.IISWebSite.DeploymentType": "webSite",
        "Octopus.Action.IISWebSite.StartWebSite": "True",
        ...
      }
    }
  }

Important: There are two run_script_action and two plain action.

Expected: The deployment process should get created with them in the order script1,action1,script2,action2 Actual: The deployment process is created with them in the order action1,action2,script1,script2

Analysis

Observing the network requests sent to the server, we see that the terraform provider is internally re-ordering the actions. The server is not at fault here.

Tracing through the code, we find that flattenDeploymentSteps - which takes an array of steps/actions from the octopus server, and stores them in the terraform state - is taking the single list of actions (within a step) from octopus, and breaking them down into multiple different lists of actions depending on type. All the run_script_actions (etc) get grouped together regardless of their order within the step. https://github.com/OctopusDeployLabs/terraform-provider-octopusdeploy/blob/c7211a7e5856285cf80bf9cd57f7ac4e0f73971c/octopusdeploy/schema_deployment_step.go#L130

The inverse of this is expandDeploymentSteps, which takes the multiple arrays from the terraform state and merges them back into a single array in order to send it to the octopus server. We can see here that it is appending all the actions one group at a time, and has lost information regarding their correct sequence within the step.

https://github.com/OctopusDeployLabs/terraform-provider-octopusdeploy/blob/c7211a7e5856285cf80bf9cd57f7ac4e0f73971c/octopusdeploy/schema_deployment_step.go#L12

Workaround

reverting to use action for all actions within a step solves the problem because it removes the unwanted grouping by action type. You can convert a run_script_action to a regular action by setting action_type = "Octopus.Script" and using properties = { "Octopus.Action.Script.ScriptBody" = <<-EOT rather than script_body = <<-EOT

e.g. (pseudocode, do not copy)

resource "octopusdeploy_deployment_process" "my_deployment_process" {
  project_id  = octopusdeploy_project.my_project.id
  step {
    condition           = "Success"
    name                = "Deploy Website"
    action {
      action_type = "Octopus.Script"
      name        = "script1"
      properties = {
        "Octopus.Action.Script.ScriptBody" = <<-EOT
          Write-Host 'Checking Server'
        EOT
      }
    }
    action {
      name          = "action1"
      action_type   = "Octopus.IIS"
      run_on_server = true

      properties = {
        "Octopus.Action.IISWebSite.DeploymentType": "webSite",
        "Octopus.Action.IISWebSite.StartWebSite": "True",
        ...
      }
    }
    action {
      action_type = "Octopus.Script"
      name        = "script2"
      properties = {
        "Octopus.Action.Script.ScriptBody" = <<-EOT
          Write-Host 'Verifying Server'
        EOT
      }
    }
    action {
      name          = "action2"
      action_type   = "Octopus.IIS"
      run_on_server = true

      properties = {
        "Octopus.Action.IISWebSite.DeploymentType": "webSite",
        "Octopus.Action.IISWebSite.StartWebSite": "True",
        ...
      }
    }
  }

borland avatar Sep 09 '22 02:09 borland