Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_container_app - Add validations for the ingress.0.traffic_weight #24042

Merged
merged 7 commits into from
Jan 8, 2024

Conversation

magodo
Copy link
Collaborator

@magodo magodo commented Nov 28, 2023

This PR adds create/update time validation for the azurerm_container_app, in that:

  • latest_revision (true) conflicts with revision_suffix (non-empty) in any case, but exactly one of them should be specified
  • At most one traffic_weight can have latest_revision set to true. Especially for creation, the latest_revision has to be true, and only one traffic_weight block can be specified

This also removes a confusion line in the document saying that the traffic_weight can't be set if revision_mode is Single, since the traffic_weight is set to Required (I assume this is to prefer explicit, instead of either using the O+C trick, or let user specify it in the ignore_changes).

Fix #20435

Copy link
Member

@jackofallops jackofallops left a comment

Choose a reason for hiding this comment

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

Hi @magodo - Thanks for this PR. I've left a few minor comments below to take a look at. Can we also add an ExpectError test to validate this new validation functionality? Should be good to go after that.

Thanks again

// Ingress traffic weight validations
if len(app.Ingress) != 0 {
ingress := app.Ingress[0]
if old, _ := metadata.ResourceDiff.GetChange("name"); old == "" {
Copy link
Member

Choose a reason for hiding this comment

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

I think we can replace this with:

Suggested change
if old, _ := metadata.ResourceDiff.GetChange("name"); old == "" {
if metadata.ResourceDiff.HasChange("name"){

since the only way this can be true is in the case of a new resource?

Copy link
Collaborator Author

@magodo magodo Dec 8, 2023

Choose a reason for hiding this comment

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

For force new resource, its first invocation on CustomizeDiff will have the name be marked as to be changed, from "some value" to null?

Copy link
Member

Choose a reason for hiding this comment

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

My understanding, based on the docs:

	//   * Existing resource, forced new: One run with state (before ForceNew),
	//     then one run without state (as if new resource)

is that the CustomizeDiff runs with the config values, not the ForceNew changes (i.e. it's run before the resource is marked for ForceNew and evaluated on the changes of config property values based on the state)

Admittedly it's been a while since I've been in this section of code, so if you have evidence of it working differently, I'm happy to have my mind changed?

Also, it's not a critical change here, just simplifies the code a little.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

By experimenting, it turns out the first invocation on CustomizeDiff for force new resource will compare the state and the config (instead of state vs null). So you are right, and I've updated the code accordingly.

Whilst one limitation to this resource is that, when users update the container app to have multiple ingress traffic weight, then they can't simply rename the resource to re-provision. The validation will fail and they'll have to manually ensure there is only one traffic weight defined as expected.

if tw.LatestRevision {
latestRevCount++
if tw.RevisionSuffix != "" {
return fmt.Errorf("`ingress.%[1]d.traffic_weight.%[1]d.revision_suffix` conflicts with `ingress.%[1]d.traffic_weight.%[1]d.latest_revision`", i)
Copy link
Member

Choose a reason for hiding this comment

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

since there can only be one ingress, this should be:

Suggested change
return fmt.Errorf("`ingress.%[1]d.traffic_weight.%[1]d.revision_suffix` conflicts with `ingress.%[1]d.traffic_weight.%[1]d.latest_revision`", i)
return fmt.Errorf("`ingress.0.traffic_weight.%[1]d.revision_suffix` conflicts with `ingress.0.traffic_weight.%[1]d.latest_revision`", i)

or the ingress index will be incorrectly incremented along with the traffic_weight index.

return fmt.Errorf("`ingress.%[1]d.traffic_weight.%[1]d.revision_suffix` conflicts with `ingress.%[1]d.traffic_weight.%[1]d.latest_revision`", i)
}
} else if tw.RevisionSuffix == "" {
return fmt.Errorf("`ingress.%[1]d.traffic_weight.%[1]d.revision_suffix` is not specified", i)
Copy link
Member

Choose a reason for hiding this comment

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

as above

Suggested change
return fmt.Errorf("`ingress.%[1]d.traffic_weight.%[1]d.revision_suffix` is not specified", i)
return fmt.Errorf("`ingress.0.traffic_weight.%d.revision_suffix` is not specified", i)

@magodo
Copy link
Collaborator Author

magodo commented Dec 8, 2023

@jackofallops Thank you for the comments! I've resolved them, and passed the test:

$ TF_ACC=1 go test -v -timeout=20h ./internal/services/containerapps -run='TestAccContainerAppResource_ingressTrafficValidation'
=== RUN   TestAccContainerAppResource_ingressTrafficValidation
=== PAUSE TestAccContainerAppResource_ingressTrafficValidation
=== CONT  TestAccContainerAppResource_ingressTrafficValidation
--- PASS: TestAccContainerAppResource_ingressTrafficValidation (10.15s)
PASS
ok      github.com/hashicorp/terraform-provider-azurerm/internal/services/containerapps 10.155s

@jackofallops
Copy link
Member

Hi @magodo - Looks like one of the existing tests contains a violation of this new validation

=== CONT  TestAccContainerAppResource_secretRemoveShouldFail
    testcase.go:113: Step 1/3 error: Error running pre-apply refresh: exit status 1
        Error: at most one `ingress.0.traffic_weight` can be specified during creation
          with azurerm_container_app.test,
          on terraform_plugin_test.tf line 130, in resource "azurerm_container_app" "test":
         130: resource "azurerm_container_app" "test" {
--- FAIL: TestAccContainerAppResource_secretRemoveShouldFail (8.59s)
FAIL

Can you take a look at fixing that up by adding a new config for the first part of the test instead of re-using the completeUpdate config? Thanks!

@magodo
Copy link
Collaborator Author

magodo commented Dec 13, 2023

@jackofallops Thank you for pointing this out! I realized that the failed test case used to pass, and it has two traffic weight configs, but still workt. The reason is that the template has revision_suffix specified, in which case you can specify it in the traffic_weight, even if you have only one traffic_weight.

The config of TestAccContainerAppResource_secretRemoveShouldFail actually has two traffic_weight blocks:

    traffic_weight {
      latest_revision = true
      percentage      = 20
    }
    traffic_weight {
      revision_suffix = "rev1"
      percentage      = 80
    }

This can make the API call successful, but the API will then deduplicate and merge them into one, effectively as:

    traffic_weight {
      latest_revision = true
      percentage      = 100
    }

or

    traffic_weight {
      revision_suffix = "rev1"
      percentage      = 100
    }

(though the API response of the traffic weight is the same as the request)

It is also worth mentioning that the order of the two traffic_weight (s) matters in that if the one with latest_revision specified appear in the latter, it will somehow override the template.0.revision_suffix, and make the next plan to show diff.

Based on this, I think we can still keep the validation as is, and change the configuration for the failing test cases so that they can pass the validation. Whilst this is a "breaking change" any way, so we shall mention that in the release note?

Test

💢  TF_ACC=1 go test -v -timeout=20h ./internal/services/containerapps -run='TestAccContainerAppResource_secretFail|TestAccContainerAppResource_removeDaprAppPort|TestAccContainerAppResource_completeUpdate'
=== RUN   TestAccContainerAppResource_completeUpdate
=== PAUSE TestAccContainerAppResource_completeUpdate
=== RUN   TestAccContainerAppResource_removeDaprAppPort
=== PAUSE TestAccContainerAppResource_removeDaprAppPort
=== RUN   TestAccContainerAppResource_secretFail
=== PAUSE TestAccContainerAppResource_secretFail
=== CONT  TestAccContainerAppResource_completeUpdate
=== CONT  TestAccContainerAppResource_secretFail
=== CONT  TestAccContainerAppResource_removeDaprAppPort
--- PASS: TestAccContainerAppResource_secretFail (805.04s)
--- PASS: TestAccContainerAppResource_completeUpdate (915.24s)
--- PASS: TestAccContainerAppResource_removeDaprAppPort (932.51s)
PASS
ok      github.com/hashicorp/terraform-provider-azurerm/internal/services/containerapps 932.519s

@github-actions github-actions bot added size/XL and removed size/M labels Dec 13, 2023
Copy link
Member

@jackofallops jackofallops left a comment

Choose a reason for hiding this comment

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

Thanks for the changes @magodo - This LGTM now 👍

@jackofallops jackofallops merged commit bb71f3e into hashicorp:main Jan 8, 2024
24 checks passed
@github-actions github-actions bot added this to the v3.87.0 milestone Jan 8, 2024
jackofallops added a commit that referenced this pull request Jan 8, 2024
dduportal pushed a commit to jenkins-infra/azure that referenced this pull request Jan 17, 2024
<Actions>
<action
id="f410411e63aff4bb73a81c2aec1d373cf8a903e63b30dee2006b0030d8a94cc8">
        <h3>Bump Terraform `azurerm` provider version</h3>
<details
id="1d9343c012f5434ac9fe8a98135bae3667b399259be16d9b14302ea3bd424a24">
            <summary>Update Terraform lock file</summary>
<p>&#34;hashicorp/azurerm&#34; updated from &#34;3.86.0&#34; to
&#34;3.87.0&#34; in file &#34;.terraform.lock.hcl&#34;</p>
            <details>
                <summary>3.87.0</summary>
<pre>Changelog retrieved
from:&#xA;&#x9;https://github.com/hashicorp/terraform-provider-azurerm/releases/tag/v3.87.0&#xA;ENHANCEMENTS:&#xA;&#xA;*
dependencies: updating to `v0.20240112.1095456` of
`github.com/hashicorp/go-azure-sdk` [GH-24477]&#xA;* dependencies:
updating to `v0.65.1` of `github.com/hashicorp/go-azure-helpers`
[GH-24479]&#xA;* `kusto`: updating to use the base layer from
`hashicorp/go-azure-sdk` rather than `Azure/go-autorest`
[GH-24477]&#xA;* `azurerm_container_group` - support for the `priority`
property [GH-24374]&#xA;* Data Source: `azurerm_application_gateway` -
support for the `trusted_client_certificate.data` property
[GH-24474]&#xA;&#xA;## 3.87.0 (January 11,
2024)&#xA;&#xA;FEATURES:&#xA;&#xA;* New Data Source:
`azurerm_network_manager`
([#24398](hashicorp/terraform-provider-azurerm#24398
New Resource:
`azurerm_security_center_server_vulnerability_assessments_setting`
([#24299](https://github.com/hashicorp/terraform-provider-azurerm/issues/24299))&#xA;&#xA;ENHANCEMENTS:&#xA;&#xA;*
dependencies: updating to `v0.20240111.1094251` of
`github.com/hashicorp/go-azure-sdk`
([#24463](hashicorp/terraform-provider-azurerm#24463
Data Source: `azurerm_mssql_database` - support for `identity`,
`transparent_data_encryption_enabled`,
`transparent_data_encryption_key_vault_key_id` and
`transparent_data_encryption_key_automatic_rotation_enabled`
([#24412](hashicorp/terraform-provider-azurerm#24412
Data Source: `azurerm_mssql_server` - support for
`transparent_data_encryption_key_vault_key_id`
([#24412](hashicorp/terraform-provider-azurerm#24412
`machinelearning`: updating to API Version `2023-10-01`
([#24416](hashicorp/terraform-provider-azurerm#24416
`paloaltonetworks`: updating to API Version `2023-09-01`
([#24290](hashicorp/terraform-provider-azurerm#24290
`azurerm_container_app` - update create time validations for
`ingress.0.traffic_weight`
([#24042](hashicorp/terraform-provider-azurerm#24042
`azurerm_container_app`- support for the `ip_security_restriction` block
([#23870](hashicorp/terraform-provider-azurerm#23870
`azurerm_kubernetes_cluster` - properties in
`default_node_pool.linux_os_config.sysctl_config` are now updateable via
node pool cycling
([#24397](hashicorp/terraform-provider-azurerm#24397
`azurerm_linux_web_app` - support the `VS2022` value for the
`remote_debugging_version` property
([#24407](hashicorp/terraform-provider-azurerm#24407
`azurerm_mssql_database` - support for `identity`,
`transparent_data_encryption_key_vault_key_id` and
`transparent_data_encryption_key_automatic_rotation_enabled`
([#24412](hashicorp/terraform-provider-azurerm#24412
`azurerm_postgres_flexible_server` - the `sku_name` property now
supports being set to `MO_Standard_E96ds_v5`
([#24367](hashicorp/terraform-provider-azurerm#24367
`azurerm_role_assignment` - support for the `principal_type` property
([#24271](hashicorp/terraform-provider-azurerm#24271
`azurerm_windows_web_app` - support the `VS2022` value for the
`remote_debugging_version` property
([#24407](hashicorp/terraform-provider-azurerm#24407
`azurerm_cdn_frontdoor_firewall_policy` - support for
`request_body_check_enabled` property
([#24406](https://github.com/hashicorp/terraform-provider-azurerm/issues/24406))&#xA;&#xA;BUG
FIXES:&#xA;&#xA;* Data Source: `azurerm_role_definition` - fix
`role_definition_id`
([#24418](hashicorp/terraform-provider-azurerm#24418
`azurerm_api_management` - the `sku_name` property can now be updated
([#24431](hashicorp/terraform-provider-azurerm#24431
`azurerm_arc_kubernetes_flux_configuration` - prevent a bug where
certain sensitive properties for `bucket` and `git_repository` were
being overwritten after an update to the resource is made
([#24066](hashicorp/terraform-provider-azurerm#24066
`azurerm_kubernetes_flux_configuration` - prevent a bug where certain
sensitive properties for `bucket` and `git_repository` were being
overwritten after an update to the resource is made
([#24066](hashicorp/terraform-provider-azurerm#24066
`azure_linux_web_app` - prevent a bug in App Service processing of
`application_stack` in updates to `site_config`
([#24424](hashicorp/terraform-provider-azurerm#24424
`azure_linux_web_app_slot` - Fix bug in App Service processing of
`application_stack` in updates to `site_config`
([#24424](hashicorp/terraform-provider-azurerm#24424
`azurerm_network_manager_deployment` - update creation wait logic to
better tolerate the api returning not found
([#24330](hashicorp/terraform-provider-azurerm#24330
`azurerm_virtual_machine_data_disk_attachment` - do not update
applications profile with disks
([#24145](hashicorp/terraform-provider-azurerm#24145
`azure_windows_web_app` - prevent a bug in App Service processing of
`application_stack` in updates to `site_config`
([#24424](hashicorp/terraform-provider-azurerm#24424
`azure_windows_web_app_slot` - prevent a bug in App Service processing
of `application_stack` in updates to `site_config`
([#24424](hashicorp/terraform-provider-azurerm#24424
`azurerm_maintenance_configuration` - set the `reboot` property in
flatten from `AlwaysReboot` to `Always`
([#24376](hashicorp/terraform-provider-azurerm#24376
`azurerm_container_app_environment` - the `workload_profile` property
can now be updated
([#24409](https://github.com/hashicorp/terraform-provider-azurerm/issues/24409))&#xA;&#xA;&#xA;</pre>
            </details>
        </details>
<a
href="https://infra.ci.jenkins.io/job/terraform-jobs/job/azure/job/main/1004/">Jenkins
pipeline link</a>
    </action>
</Actions>

---

<table>
  <tr>
    <td width="77">
<img src="https://www.updatecli.io/images/updatecli.png" alt="Updatecli
logo" width="50" height="50">
    </td>
    <td>
      <p>
Created automatically by <a
href="https://www.updatecli.io/">Updatecli</a>
      </p>
      <details><summary>Options:</summary>
        <br />
<p>Most of Updatecli configuration is done via <a
href="https://www.updatecli.io/docs/prologue/quick-start/">its
manifest(s)</a>.</p>
        <ul>
<li>If you close this pull request, Updatecli will automatically reopen
it, the next time it runs.</li>
<li>If you close this pull request and delete the base branch, Updatecli
will automatically recreate it, erasing all previous commits made.</li>
        </ul>
        <p>
Feel free to report any issues at <a
href="https://github.com/updatecli/updatecli/issues">github.com/updatecli/updatecli</a>.<br
/>
If you find this tool useful, do not hesitate to star <a
href="https://github.com/updatecli/updatecli/stargazers">our GitHub
repository</a> as a sign of appreciation, and/or to tell us directly on
our <a
href="https://matrix.to/#/#Updatecli_community:gitter.im">chat</a>!
        </p>
      </details>
    </td>
  </tr>
</table>

Co-authored-by: Jenkins Infra Bot (updatecli) <[email protected]>
Copy link

github-actions bot commented May 1, 2024

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

azurerm_container_app - Cannot deploy container with ingress enabled
2 participants