terraform-provider-ec
terraform-provider-ec copied to clipboard
updates to ec_deployment resource destroys ec_deployment_traffic_filter_association resources
Readiness Checklist
- [x] I am running the latest version
- [x] I checked the documentation and found no answer
- [x] I checked to make sure that this issue has not already been filed
- [x] 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
- Create a project using the above terraform snippet and set the used variables
- Run terraform apply (we are using provider v 0.3.0)
- Log into the Elastic Cloud console and add in an additional IP traffic filter for your own IP address.
- Associate the traffic filter created in (3) with the deployment created in (2).
- Confirm that the traffic filter is working by accessing the Kibana instance via the console
- Rerun step (2)
- 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
I have a same problem
Same issue here.
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:
- Importing your changes back to Terraform after doing it manually
- Using
lifecyclearguments (see https://www.terraform.io/language/meta-arguments/lifecycle) to control the Terraform lifecycle behavior.
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.
@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
.tffile 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 byterraform apply. - After completion, run
terraform applyagain. 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 applyagain 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.
Are there any progress on this for last year?
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.