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

updates to ec_deployment resource destroys ec_deployment_traffic_filter_association resources #419

Closed
4 tasks done
chrisjprior opened this issue Dec 20, 2021 · 7 comments · Fixed by #632
Closed
4 tasks done
Labels
bug Something isn't working
Milestone

Comments

@chrisjprior
Copy link

chrisjprior commented Dec 20, 2021

Readiness Checklist

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed
  • I am reporting the issue to the correct repository (for multi-repository projects)

Expected Behavior

When applying an update to ec_deployment resource without the traffic_filter attribute set, terraform should not destroy related ec_deployment_traffic_filter_association resources.

From the documentation:

Note on traffic filters
If you use traffic_filter on an ec_deployment, Terraform will manage the full set of traffic rules for the deployment, and treat additional traffic filters as drift. For this reason, traffic_filter cannot be mixed with the ec_deployment_traffic_filter_association resource for a given deployment.

Current Behavior

ec_deployment_traffic_filter_association resources linked to the ec_deployment resource which is being updated are destroyed. The provider is treating the ec_deployment resource as if it has its traffic_filter attribute set to an empty list.

Terraform Definition

data "ec_stack" "stack" {
  version_regex = var.stack_version
  region        = var.region
}

resource "ec_deployment" "elasticsearch" {
  name = var.name

  region                 = data.ec_stack.stack.region
  version                = data.ec_stack.stack.version
  deployment_template_id = "aws-general-purpose" 

  elasticsearch {
    autoscale = "false"
    topology {
      id = "hot_content"
      size = "8g"
      zone_count = length(var.azs)
    }

    trust_account {
      account_id = data.external.account.result.id
      trust_all = false
      trust_allowlist = []
    }
  }

  kibana {
    topology {
      size = "1g"
      zone_count = length(var.azs)
    }
  }

 apm {
   topology {
     size = "1g"
   }
 }
 
  tags = {
    Name = var.name
  }
}

resource "ec_deployment_traffic_filter" "deny" {
  name   = "DENY"
  region = data.ec_stack.stack.region
  type   = "ip"

  rule {
    source = "127.0.0.1/32"
  }
}

resource "ec_deployment_traffic_filter_association" "deny" {
  traffic_filter_id = ec_deployment_traffic_filter.deny.id
  deployment_id     = ec_deployment.elasticsearch.id
}

Steps to Reproduce

  1. Create a project using the above terraform snippet and set the used variables
  2. Run terraform apply (we are using provider v 0.3.0)
  3. Log into the Elastic Cloud console and add in an additional IP traffic filter for your own IP address.
  4. Associate the traffic filter created in (3) with the deployment created in (2).
  5. Confirm that the traffic filter is working by accessing the Kibana instance via the console
  6. Rerun step (2)
  7. Confirm that the traffic filter created in step (3) is no longer associated with the deployment created in step (2).

Context

There doesn't seem to be anyway to apply an update to the ec_deployment resource without destroying the associated traffic filters.

My specific use case requires me to be able to create an ec_deployment and then separately and at a later time create and destroy additional traffic filters on that resource. This would allow us to create and destroy log shippers to ingest data without impacting the ec_deployment resource. While this is possible any subsequent update to the ex_deployment resource removes all the associations.

Possible Solution

Potential fix might be to check if the traffic_filter attribute exists and if it doesn't forgo updating the traffic filters during the ec_deployment resource update. This check is done to determine if the resource has changed but the traffic filters are then updated regardless.

Your Environment

  • Version used: 0.3.0
  • Running against Elastic Cloud SaaS.
  • Operating System and version: Ubuntu Latest
@chrisjprior chrisjprior added bug Something isn't working Team:Delivery labels Dec 20, 2021
@euskadi31
Copy link

I have a same problem

@ponceps
Copy link

ponceps commented Jan 14, 2022

Same issue here.

@artemnikitin
Copy link
Member

artemnikitin commented Jan 20, 2022

Hi folks, based on the description, it looks like you are trying to modify resources created by Terraform outside of Terraform. This will obviously cause a drift. Based on the description, it looks like our Terraform provider is behaving as expected in the case of drift.

I would suggest 2 possible options:

@chrisjprior
Copy link
Author

Hi @artemnikitin thanks for getting back to me.

I can't agree that this is the expected behaviour and I am not managing resources outside of terraform. I am however using multiple separate terraform state files to manage different resources, something which I have done successfully in similar scenarios with other providers for some time.

I have the following state files:

  • I have a state file which creates the ec_deployment resource, a traffic filter which blocks all ingress and an association between the 2.
  • I then have multiple environments which generate data for ingestion into Elastic and for each environment I need to add a traffic filter to allow connectivity to the elastic cluster. Since I want to create these environments independently of the Elastic cluster I give each its own state file in which the traffic filters are created and associated back to the ec_deployment resource via the data source.

The following is a quote from the doc for the ec_deployment resources:
"Note on traffic filters
If you use traffic_filter on an ec_deployment, Terraform will manage the full set of traffic rules for the deployment, and treat additional traffic filters as drift. For this reason, traffic_filter cannot be mixed with the ec_deployment_traffic_filter_association resource for a given deployment."

This implies that if you avoid using traffic_filter on ec_deployment terraform will not manage the filters via that resource allowing the use of the traffic_filter and ec_deployment_traffic_filter_association resources, unyet any attempt to deploy a state file which does not contain all the association resources results in terraform treating it as a diff and removing them.

I cannot speak to the intended behaviour but its my opinion that the provider in this case does not behave as I would expect based on the docs.

I also looked at the code and was able to create a clone which works as I expected, it is interesting to note that there is code which excludes the traffic_filter attribute of ec_deployment when determining if changes have been made to the resource but this is then ignored and the update to the filters carried out anyway.

As to workarounds for this issue, I ended up using the terraform lifecycle argument to ignore the attribute on the ec_deployment resource as follows:
lifecycle { ignore_changes = [ traffic_filter ] }

Again thanks for responding, hopefully the above assists in improving the solution / docs or failing that at least provides clarification for others encountering this issue.

@bsamseth
Copy link

bsamseth commented Feb 19, 2022

@artemnikitin I just wanted to chime in with a minimal, self-contained example that shows that this is indeed a bug.

Even if this can be worked around with a lifetime argument, at the very least the docs should be updated accordingly.

To reproduce:

  • In an empty folder, make a .tf file with this content:
terraform {
  required_version = ">= 1.1.0"
  required_providers {
    ec = {
      source  = "elastic/ec"
      version = "~> 0.3.0"
    }
  }
}

data "ec_stack" "latest" {
  version_regex = "latest"
  region        = "us-east-1"
}

resource "ec_deployment" "example_minimal" {
  name                   = "my_example_deployment"
  region                 = "us-east-1"
  version                = data.ec_stack.latest.version
  deployment_template_id = "aws-io-optimized-v2"

  elasticsearch {}

  kibana {}

  apm {}

  enterprise_search {}
}


resource "ec_deployment_traffic_filter" "this" {
  name   = "example-filter"
  region = "us-east-1"
  type   = "ip"

  rule {
    source = "0.0.0.0/0"
  }
}

resource "ec_deployment_traffic_filter_association" "this" {
  deployment_id     = ec_deployment.example_minimal.id
  traffic_filter_id = ec_deployment_traffic_filter.this.id
}
  • (Set env. var. EC_API_KEY)
  • Run terraform init, followed by terraform apply.
  • After completion, run terraform apply again. You will get something like this:
Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # ec_deployment.example_minimal has changed
  ~ resource "ec_deployment" "example_minimal" {
        id                     = "..."
        name                   = "my_example_deployment"
      + tags                   = {}
      + traffic_filter         = [
          + "6068d9a24c1d40f9ae6d2cb6e0d3afb3",
        ]
        # (7 unchanged attributes hidden)
        # (4 unchanged blocks hidden)
    }


Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using
ignore_changes, the following plan may include actions to undo or respond to these changes.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # ec_deployment.example_minimal will be updated in-place
  ~ resource "ec_deployment" "example_minimal" {
        id                     = "..."
        name                   = "my_example_deployment"
        tags                   = {}
      ~ traffic_filter         = [
          - "6068d9a24c1d40f9ae6d2cb6e0d3afb3",
        ]
        # (7 unchanged attributes hidden)
        # (4 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
  • Run terraform apply again and you get
Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # ec_deployment_traffic_filter_association.this has been deleted
  - resource "ec_deployment_traffic_filter_association" "this" {
      - deployment_id     = "..." -> null
      - id                = "3438189230" -> null
      - traffic_filter_id = "6068d9a24c1d40f9ae6d2cb6e0d3afb3" -> null
    }


Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using
ignore_changes, the following plan may include actions to undo or respond to these changes.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
  + create

Terraform will perform the following actions:

  # ec_deployment_traffic_filter_association.this will be created
  + resource "ec_deployment_traffic_filter_association" "this" {
      + deployment_id     = "..."
      + id                = (known after apply)
      + traffic_filter_id = "6068d9a24c1d40f9ae6d2cb6e0d3afb3"
    }

Plan: 1 to add, 0 to change, 0 to destroy.
  • Run apply again and you are back where you started and the process continues.

@asychev
Copy link

asychev commented Dec 15, 2022

Are there any progress on this for last year?

@Jacendb
Copy link

Jacendb commented Dec 15, 2022

The workaround I use is adding this to the ec_deployment resources:

    ignore_changes = [
      traffic_filter, elasticsearch[0].config, kibana[0].config
    ]
  }

I add the respective config so terraform doesn't wipe some required manual updates we have in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
9 participants