Skip to content

feat(workflows): Adds more optional fields to workflows#997

Open
d0weinberger wants to merge 1 commit intomainfrom
feat/add-more-fields-to-workflows
Open

feat(workflows): Adds more optional fields to workflows#997
d0weinberger wants to merge 1 commit intomainfrom
feat/add-more-fields-to-workflows

Conversation

@d0weinberger
Copy link
Collaborator

@d0weinberger d0weinberger commented Feb 24, 2026

Why this PR?

The dynatrace_automation_workflow resource was missing several fields supported by the Dynatrace Automation API. Users couldn’t configure important workflow properties like deployment state, execution limits, or workflow-level input parameters, forcing them to manage these settings outside of Terraform.

What has changed?

New workflow-level attributes (all Optional, non-breaking):

HCL Attribute Type Default Description
is_deployed bool true Controls whether the workflow is active and billed, or a draft
owner_type string - Enum: USER / GROUP - type of the workflow owner
hourly_execution_limit int 1000 Cap on executions per hour
input string (JSON) - Workflow-level input parameters available to all tasks
task_defaults string (JSON) - Default settings applied to all tasks
guide string - Markdown guide text for the workflow (max 10,000 chars)
result string - Result identifier for the workflow

How does it do it?

All changes follow established patterns in this provider:

  • Added struct fields to Workflow with correct JSON tags.
  • Extended Terraform schema in Schema() with appropriate types, defaults, and validation (StringInSlice, ValidateMaxLength, SuppressJSONorEOT).
  • Implemented is_deployed using the *bool + GetOkExists pattern (same as existing isPrivate) to avoid TF SDK default/zero-value pitfalls.
  • Implemented input and task_defaults using the existing JSON-string pattern (like Task.Input): map[string]any in Go/API, jsonencode() in HCL.
  • Updated MarshalJSON to include all new fields in the custom serialization struct (which injects schemaVersion).
  • Updated MarshalHCL / UnmarshalHCL to encode/decode the new fields.

How is it tested?

I added a new Terraform file for E2E testing using the newly introduced fields.

How does it affect users?

  • No breaking changes — all new fields are Optional and defaults align with API behavior; existing configurations keep working.
  • No state migration needed — additive Optional fields don’t require schema version bumps.
  • Users can now manage workflow deployment state, execution limits, input parameters, task defaults, and guides entirely through Terraform.

Issue: CA-18196

@d0weinberger d0weinberger marked this pull request as ready for review February 24, 2026 13:20
@d0weinberger d0weinberger force-pushed the feat/add-more-fields-to-workflows branch from c522375 to e9fa086 Compare February 24, 2026 13:30
Type: schema.TypeString,
Description: "Informational guide text for the workflow",
Optional: true,
ValidateDiagFunc: ValidateMaxLength(10000),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We agreed not to validate field lengths, since the API might change, right?
Could you remove it?

Type: schema.TypeString,
Description: "The type of the owner. Possible values are `USER` and `GROUP`",
Optional: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { return new == "" },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for the DiffSupressFunc here? Is there a different behavior (sent data vs received data)?

task_defaults = jsonencode({
"timeout" : 3600
})
guide = chomp(<<-EOT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to keep this huge markdown?
I don't see a real benefit in having it, and it would just reduce the readability and also maintainability of the example files. For testing, a short string would be enough

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nit, but is new_fields a good pick for a name? If new properties come in, will there be a new-fields2.tf? 😅

Comment on lines +160 to +162
if me.IsDeployed == nil {
me.IsDeployed = opt.NewBool(true)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, the value on the API side can still be undefined, even if it has a default value?
When running locally, without is_deployed, the value is always defined for me

Comment on lines +269 to +275
// Same pattern as `private` — `isDeployed` defaults to `true`
isDeployed, isDeployedExists := decoder.GetOkExists("is_deployed")
if !isDeployedExists {
me.IsDeployed = opt.NewBool(true)
} else {
me.IsDeployed = opt.NewBool(isDeployed.(bool))
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of Default: true, the is_deployed should always be set, right?

Here I haven't set the is_deployed
Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants