From 7c5b95bbcc2a812c006311c15b9e924aa92f4d47 Mon Sep 17 00:00:00 2001 From: Moritz Sanft <58110325+msanft@users.noreply.github.com> Date: Mon, 18 Dec 2023 13:55:44 +0100 Subject: [PATCH] terraform-provider: warn about microservice version changes (#2730) * terraform-provider: update data source examples * terraform-provider: warn about destructive microservice changes * terraform-provider: use `name` variable * terraform-provider: only perform pre-apply checks on upgrades * terraform-provider: fix conditional * terraform-provider: remove obsolete version checks --- .../docs/data-sources/attestation.md | 4 ++- .../docs/data-sources/image.md | 2 +- .../constellation_attestation/data-source.tf | 4 ++- .../constellation_image/data-source.tf | 2 +- .../examples/full/aws_cluster.tf | 4 +-- .../internal/provider/cluster_resource.go | 34 ++++++++++++++++++- 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/terraform-provider-constellation/docs/data-sources/attestation.md b/terraform-provider-constellation/docs/data-sources/attestation.md index 91535d724..a8668dfdd 100644 --- a/terraform-provider-constellation/docs/data-sources/attestation.md +++ b/terraform-provider-constellation/docs/data-sources/attestation.md @@ -13,10 +13,12 @@ Data source to fetch an attestation configuration for a given cloud service prov ## Example Usage ```terraform +data "constellation_image" "example" {} # Fill accordingly for the CSP + data "constellation_attestation" "test" { csp = "aws" attestation_variant = "aws-sev-snp" - image_version = "v2.13.0" + image = data.constellation_image.example.image } ``` diff --git a/terraform-provider-constellation/docs/data-sources/image.md b/terraform-provider-constellation/docs/data-sources/image.md index 6c351e6f5..2e357495d 100644 --- a/terraform-provider-constellation/docs/data-sources/image.md +++ b/terraform-provider-constellation/docs/data-sources/image.md @@ -14,7 +14,7 @@ Data source to resolve the CSP-specific OS image reference for a given version a ```terraform data "constellation_image" "example" { - image_version = "v2.13.0" + version = "v2.13.0" attestation_variant = "aws-sev-snp" csp = "aws" region = "eu-west-1" diff --git a/terraform-provider-constellation/examples/data-sources/constellation_attestation/data-source.tf b/terraform-provider-constellation/examples/data-sources/constellation_attestation/data-source.tf index 4b40c0a69..a831d03f3 100644 --- a/terraform-provider-constellation/examples/data-sources/constellation_attestation/data-source.tf +++ b/terraform-provider-constellation/examples/data-sources/constellation_attestation/data-source.tf @@ -1,5 +1,7 @@ +data "constellation_image" "example" {} # Fill accordingly for the CSP + data "constellation_attestation" "test" { csp = "aws" attestation_variant = "aws-sev-snp" - image_version = "v2.13.0" + image = data.constellation_image.example.image } diff --git a/terraform-provider-constellation/examples/data-sources/constellation_image/data-source.tf b/terraform-provider-constellation/examples/data-sources/constellation_image/data-source.tf index b1ab019b6..9ff1fe095 100644 --- a/terraform-provider-constellation/examples/data-sources/constellation_image/data-source.tf +++ b/terraform-provider-constellation/examples/data-sources/constellation_image/data-source.tf @@ -1,5 +1,5 @@ data "constellation_image" "example" { - image_version = "v2.13.0" + version = "v2.13.0" attestation_variant = "aws-sev-snp" csp = "aws" region = "eu-west-1" diff --git a/terraform-provider-constellation/examples/full/aws_cluster.tf b/terraform-provider-constellation/examples/full/aws_cluster.tf index 73ca986e8..5d41036d5 100644 --- a/terraform-provider-constellation/examples/full/aws_cluster.tf +++ b/terraform-provider-constellation/examples/full/aws_cluster.tf @@ -39,14 +39,14 @@ resource "random_bytes" "measurement_salt" { module "aws_iam" { // replace $VERSION with the Constellation version you want to use, e.g., v2.14.0 source = "https://github.com/edgelesssys/constellation/releases/download/$VERSION/terraform-module.zip//terraform-module/iam/aws" - name_prefix = "constell" + name_prefix = local.name region = local.region } module "aws_infrastructure" { // replace $VERSION with the Constellation version you want to use, e.g., v2.14.0 source = "https://github.com/edgelesssys/constellation/releases/download/$VERSION/terraform-module.zip//terraform-module/aws" - name = "constell" + name = local.name node_groups = { control_plane_default = { role = "control-plane" diff --git a/terraform-provider-constellation/internal/provider/cluster_resource.go b/terraform-provider-constellation/internal/provider/cluster_resource.go index 421c5c16c..040a84269 100644 --- a/terraform-provider-constellation/internal/provider/cluster_resource.go +++ b/terraform-provider-constellation/internal/provider/cluster_resource.go @@ -50,6 +50,7 @@ import ( var ( _ resource.Resource = &ClusterResource{} _ resource.ResourceWithImportState = &ClusterResource{} + _ resource.ResourceWithModifyPlan = &ClusterResource{} ) // NewClusterResource creates a new cluster resource. @@ -344,6 +345,35 @@ func (r *ClusterResource) Configure(_ context.Context, req resource.ConfigureReq } } +// ModifyPlan is called when the resource is planned for creation, updates, or deletion. This allows to set pre-apply +// warnings and errors. +func (r *ClusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { + // Checks running on updates to the resource. (i.e. state and plan != nil) + if !req.Plan.Raw.IsNull() && !req.State.Raw.IsNull() { + // Read currentState supplied by Terraform runtime into the model + var currentState ClusterResourceModel + resp.Diagnostics.Append(req.State.Get(ctx, ¤tState)...) + if resp.Diagnostics.HasError() { + return + } + + // Read plannedState supplied by Terraform runtime into the model + var plannedState ClusterResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plannedState)...) + if resp.Diagnostics.HasError() { + return + } + + // Warn the user about possibly destructive changes in case microservice changes are to be applied. + if currentState.MicroserviceVersion.ValueString() != plannedState.MicroserviceVersion.ValueString() { + resp.Diagnostics.AddWarning("Microservice version change", + "Changing the microservice version can be a destructive operation.\n"+ + "Upgrading cert-manager will destroy all custom resources you have manually created that are based on the current version of cert-manager.\n"+ + "It is recommended to backup the cluster's CRDs before applying this change.") + } + } +} + // Create is called when the resource is created. func (r *ClusterResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { // Read data supplied by Terraform runtime into the model @@ -849,7 +879,9 @@ func (r *ClusterResource) applyHelmCharts(ctx context.Context, applier *constell Conformance: false, // Conformance mode does't need to be configurable through the TF provider for now. HelmWaitMode: helm.WaitModeAtomic, ApplyTimeout: 10 * time.Minute, - AllowDestructive: helm.DenyDestructive, + // Allow destructive changes to the cluster. + // The user has previously been warned about this when planning a microservice version change. + AllowDestructive: helm.AllowDestructive, } executor, _, err := applier.PrepareHelmCharts(options, state,