Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions octopusdeploy/schema_action_apply_terraform_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ func addTerraformTemplateAdvancedOptionsSchema(element *schema.Resource) {
}
}

func addTerraformTemplatePlanSchema(element *schema.Resource) {
element.Schema["is_plan"] = &schema.Schema{
Optional: true,
Type: schema.TypeBool,
Default: false,
Description: "Determines whether the action only generates a terraform plan",
}
}

func addTerraformTemplateAwsAccountSchema(element *schema.Resource) {
element.Schema["aws_account"] = &schema.Schema{
Elem: &schema.Resource{
Expand Down Expand Up @@ -166,10 +175,7 @@ func flattenTerraformTemplate(properties map[string]octopusdeploy.PropertyValue)
return []interface{}{flattenedMap}
}

func expandApplyTerraformTemplateAction(flattenedAction map[string]interface{}) *octopusdeploy.DeploymentAction {
action := expandAction(flattenedAction)
action.ActionType = "Octopus.TerraformApply"

func expandTerraformTemplateAction(flattenedAction map[string]interface{}, action *octopusdeploy.DeploymentAction) {
if v, ok := flattenedAction["template"]; ok {
template := v.(*schema.Set).List()[0].(map[string]interface{})

Expand Down Expand Up @@ -275,7 +281,15 @@ func expandApplyTerraformTemplateAction(flattenedAction map[string]interface{})
action.Properties["Octopus.Action.AzureAccount.Variable"] = octopusdeploy.NewPropertyValue(v.(string), false)
}
}

}
func expandApplyTerraformTemplateAction(flattenedAction map[string]interface{}) *octopusdeploy.DeploymentAction {
action := expandAction(flattenedAction)
if isPlan, ok := flattenedAction["is_plan"].(bool); ok && isPlan {
action.ActionType = "Octopus.TerraformPlan"
} else {
action.ActionType = "Octopus.TerraformApply"
}
expandTerraformTemplateAction(flattenedAction, action)
return action
}

Expand Down Expand Up @@ -369,7 +383,7 @@ func flattenTerraformTemplateAzureAccount(properties map[string]octopusdeploy.Pr
return []interface{}{flattenedMap}
}

func flattenApplyTerraformTemplateAction(action *octopusdeploy.DeploymentAction) map[string]interface{} {
func flattenTerraformTemplateAction(action *octopusdeploy.DeploymentAction) map[string]interface{} {
flattenedAction := flattenAction(action)

for k, v := range action.Properties {
Expand Down Expand Up @@ -401,9 +415,10 @@ func flattenApplyTerraformTemplateAction(action *octopusdeploy.DeploymentAction)
return flattenedAction
}

func getApplyTerraformTemplateActionSchema() *schema.Schema {
func getTerraformTemplateActionSchema() *schema.Schema {
actionSchema, element := getActionSchema()
addExecutionLocationSchema(element)
addTerraformTemplatePlanSchema(element)
addTerraformTemplateAdvancedOptionsSchema(element)
addTerraformTemplateAwsAccountSchema(element)
addTerraformTemplateAzureAccountSchema(element)
Expand Down
20 changes: 13 additions & 7 deletions octopusdeploy/schema_action_apply_terraform_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestAccOctopusDeployApplyTerraformAction(t *testing.T) {
name := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
pluginCacheDirectory := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
runOnServer := acctest.RandIntRange(0, 2) == 0
isPlan := acctest.RandIntRange(0, 2) == 0
workspace := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)

scriptSource := "Inline"
Expand Down Expand Up @@ -45,19 +46,20 @@ func TestAccOctopusDeployApplyTerraformAction(t *testing.T) {
Steps: []resource.TestStep{
{
Check: resource.ComposeTestCheckFunc(
testAccCheckApplyTerraformAction(name, runOnServer, scriptSource, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace, source, parameters),
testAccCheckApplyTerraformAction(name, runOnServer, isPlan, scriptSource, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace, source, parameters),
),
Config: testAccApplyTerraformAction(name, runOnServer, scriptSource, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace, source, parameters),
Config: testAccApplyTerraformAction(name, runOnServer, isPlan, scriptSource, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace, source, parameters),
},
},
})
}

func testAccApplyTerraformAction(name string, runOnServer bool, templateSource string, allowPluginDownloads bool, applyParameters string, initParameters string, pluginCacheDirectory string, workspace string, template string, templateParameters string) string {
func testAccApplyTerraformAction(name string, runOnServer bool, isPlan bool, templateSource string, allowPluginDownloads bool, applyParameters string, initParameters string, pluginCacheDirectory string, workspace string, template string, templateParameters string) string {
return testAccBuildTestAction(fmt.Sprintf(`
apply_terraform_template_action {
name = "%s"
run_on_server = %v
is_plan = %v

template {
additional_variable_files = "additional-variable-files"
Expand Down Expand Up @@ -95,10 +97,10 @@ func testAccApplyTerraformAction(name string, runOnServer bool, templateSource s
package_id = "MyPackage"
feed_id = "feeds-builtin"
}
}`, name, runOnServer, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace))
}`, name, runOnServer, isPlan, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace))
}

func testAccCheckApplyTerraformAction(name string, runOnServer bool, scriptSource string, allowPluginDownloads bool, applyParameters string, initParameters string, pluginCacheDirectory string, workspace string, source string, parameters string) resource.TestCheckFunc {
func testAccCheckApplyTerraformAction(name string, runOnServer bool, isPlan bool, scriptSource string, allowPluginDownloads bool, applyParameters string, initParameters string, pluginCacheDirectory string, workspace string, source string, parameters string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := testAccProvider.Meta().(*octopusdeploy.Client)

Expand All @@ -109,8 +111,12 @@ func testAccCheckApplyTerraformAction(name string, runOnServer bool, scriptSourc

action := process.Steps[0].Actions[0]

if action.ActionType != "Octopus.TerraformApply" {
return fmt.Errorf("Action type is incorrect: %s", action.ActionType)
if !isPlan && action.ActionType != "Octopus.TerraformApply" {
return fmt.Errorf("Action type is incorrect: %s, isPlan: %s", action.ActionType, strconv.FormatBool(isPlan))
}

if isPlan && action.ActionType != "Octopus.TerraformPlan" {
return fmt.Errorf("Action type is incorrect: %s, isPlan: %s", action.ActionType, strconv.FormatBool(isPlan))
}

if action.Properties["Octopus.Action.Terraform.AdditionalInitParams"].Value != initParameters {
Expand Down
17 changes: 17 additions & 0 deletions octopusdeploy/schema_action_destroy_terraform_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package octopusdeploy

import (
"github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy"
)

func expandDestroyTerraformTemplateAction(flattenedAction map[string]interface{}) *octopusdeploy.DeploymentAction {
action := expandAction(flattenedAction)
if isPlan, ok := flattenedAction["is_plan"].(bool); ok && isPlan {
action.ActionType = "Octopus.TerraformPlanDestroy"
} else {
action.ActionType = "Octopus.TerraformDestroy"
}
expandTerraformTemplateAction(flattenedAction, action)

return action
}
132 changes: 132 additions & 0 deletions octopusdeploy/schema_action_destroy_terraform_template_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package octopusdeploy

import (
"fmt"
"strconv"
"testing"

"github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccOctopusDeployDestroyTerraformAction(t *testing.T) {
allowPluginDownloads := acctest.RandIntRange(0, 2) == 0
applyParameters := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
initParameters := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
name := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
pluginCacheDirectory := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
runOnServer := acctest.RandIntRange(0, 2) == 0
isPlan := acctest.RandIntRange(0, 2) == 0
workspace := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)

scriptSource := "Inline"
if acctest.RandIntRange(0, 2) == 0 {
scriptSource = "Package"
}

parameters := ""
source := ""
if scriptSource == "Inline" {
variableName := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
variableValue := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
source = fmt.Sprintf(`variable \"%s\" { type = string }`, variableName)
parameters = fmt.Sprintf(`{\"%s\":\"%s\"}`, variableName, variableValue)
}

resource.Test(t, resource.TestCase{
CheckDestroy: resource.ComposeTestCheckFunc(
testAccProjectCheckDestroy,
testAccProjectGroupCheckDestroy,
testAccLifecycleCheckDestroy,
),
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Check: resource.ComposeTestCheckFunc(
testAccCheckDestroyTerraformAction(name, runOnServer, isPlan, scriptSource, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace, source, parameters),
),
Config: testAccDestroyTerraformAction(name, runOnServer, isPlan, scriptSource, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace, source, parameters),
},
},
})
}

func testAccDestroyTerraformAction(name string, runOnServer bool, isPlan bool, templateSource string, allowPluginDownloads bool, applyParameters string, initParameters string, pluginCacheDirectory string, workspace string, template string, templateParameters string) string {
return testAccBuildTestAction(fmt.Sprintf(`
destroy_terraform_template_action {
name = "%s"
run_on_server = %v
is_plan = %v

template {
additional_variable_files = "additional-variable-files"
directory = "template-directory"
run_automatic_file_substitution = false
target_files = "target-files"
}

advanced_options {
allow_additional_plugin_downloads = %v
apply_parameters = "%s"
init_parameters = "%s"
plugin_cache_directory = "%s"
workspace = "%s"
}

aws_account {
region = "us-east-1"
variable = "foo"
use_instance_role = true

role {
arn = "arn"
external_id = "external-id"
role_session_name = "role-session-name"
session_duration = 1800
}
}

azure_account {
variable = "qwe"
}

primary_package {
package_id = "MyPackage"
feed_id = "feeds-builtin"
}
}`, name, runOnServer, isPlan, allowPluginDownloads, applyParameters, initParameters, pluginCacheDirectory, workspace))
}

func testAccCheckDestroyTerraformAction(name string, runOnServer bool, isPlan bool, scriptSource string, allowPluginDownloads bool, applyParameters string, initParameters string, pluginCacheDirectory string, workspace string, source string, parameters string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := testAccProvider.Meta().(*octopusdeploy.Client)

process, err := getDeploymentProcess(s, client)
if err != nil {
return err
}

action := process.Steps[0].Actions[0]

if !isPlan && action.ActionType != "Octopus.TerraformDestroy" {
return fmt.Errorf("Action type is incorrect: %s, isPlan: %s", action.ActionType, strconv.FormatBool(isPlan))
}

if isPlan && action.ActionType != "Octopus.TerraformPlanDestroy" {
return fmt.Errorf("Action type is incorrect: %s, isPlan: %s", action.ActionType, strconv.FormatBool(isPlan))
}

if action.Properties["Octopus.Action.Terraform.AdditionalInitParams"].Value != initParameters {
return fmt.Errorf("AdditionalInitParams: %s", action.Properties["Octopus.Action.Terraform.AdditionalInitParams"].Value)
}

if v, _ := strconv.ParseBool(action.Properties["Octopus.Action.Terraform.AllowPluginDownloads"].Value); v != allowPluginDownloads {
return fmt.Errorf("AllowPluginDownloads: %s", action.Properties["Octopus.Action.Terraform.AllowPluginDownloads"].Value)
}

return nil
}
}
28 changes: 19 additions & 9 deletions octopusdeploy/schema_deployment_step.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ func expandDeploymentStep(flattenedStep map[string]interface{}) *octopusdeploy.D
}
}

if v, ok := flattenedStep["destroy_terraform_template_action"]; ok {
for _, tfAction := range v.([]interface{}) {
action := expandDestroyTerraformTemplateAction(tfAction.(map[string]interface{}))
step.Actions = append(step.Actions, *action)
}
}

if v, ok := flattenedStep["run_script_action"]; ok {
for _, tfAction := range v.([]interface{}) {
action := expandRunScriptAction(tfAction.(map[string]interface{}))
Expand Down Expand Up @@ -138,8 +145,10 @@ func flattenDeploymentSteps(deploymentSteps []octopusdeploy.DeploymentStep) []ma
flattenedDeploymentSteps[key]["run_script_action"] = []interface{}{flattenRunScriptAction(&deploymentStep.Actions[i])}
case "Octopus.TentaclePackage":
flattenedDeploymentSteps[key]["deploy_package_action"] = []interface{}{flattenDeployPackageAction(&deploymentStep.Actions[i])}
case "Octopus.TerraformApply":
flattenedDeploymentSteps[key]["apply_terraform_template_action"] = []interface{}{flattenApplyTerraformTemplateAction(&deploymentStep.Actions[i])}
case "Octopus.TerraformApply", "Octopus.TerraformPlan":
flattenedDeploymentSteps[key]["apply_terraform_template_action"] = []interface{}{flattenTerraformTemplateAction(&deploymentStep.Actions[i])}
case "Octopus.TerraformDestroy", "Octopus.TerraformPlanDestroy":
flattenedDeploymentSteps[key]["destroy_terraform_template_action"] = []interface{}{flattenTerraformTemplateAction(&deploymentStep.Actions[i])}
case "Octopus.WindowsService":
flattenedDeploymentSteps[key]["deploy_windows_service_action"] = []interface{}{flattenDeployWindowsServiceAction(&deploymentStep.Actions[i])}
default:
Expand All @@ -156,7 +165,7 @@ func getDeploymentStepSchema() *schema.Schema {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"action": getDeploymentActionSchema(),
"apply_terraform_template_action": getApplyTerraformTemplateActionSchema(),
"apply_terraform_template_action": getTerraformTemplateActionSchema(),
"condition": {
Default: "Success",
Description: "When to run the step, one of 'Success', 'Failure', 'Always' or 'Variable'",
Expand All @@ -175,12 +184,13 @@ func getDeploymentStepSchema() *schema.Schema {
Optional: true,
Type: schema.TypeString,
},
"deploy_kubernetes_secret_action": getDeployKubernetesSecretActionSchema(),
"deploy_package_action": getDeployPackageActionSchema(),
"deploy_windows_service_action": getDeployWindowsServiceActionSchema(),
"id": getIDSchema(),
"manual_intervention_action": getManualInterventionActionSchema(),
"name": getNameSchema(true),
"deploy_kubernetes_secret_action": getDeployKubernetesSecretActionSchema(),
"deploy_package_action": getDeployPackageActionSchema(),
"deploy_windows_service_action": getDeployWindowsServiceActionSchema(),
"destroy_terraform_template_action": getTerraformTemplateActionSchema(),
"id": getIDSchema(),
"manual_intervention_action": getManualInterventionActionSchema(),
"name": getNameSchema(true),
"package_requirement": {
Default: "LetOctopusDecide",
Description: "Whether to run this step before or after package acquisition (if possible)",
Expand Down