-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
issues creating a google_compute_security_policy with rules created in dynamic blocks #14178
Comments
@abby-embree-airship dynamic is a Terraform feature and I can't really commit much on that. But before you apply any content changes, did you see any diffs in the plan after the import? If yes, you probably need to fix that first before moving to the next step. Maybe to start without dynamic? |
@edwardmedia importing an existing resource then running a terraform plan with a rule created via a dynamic block produced the provider errors I included in the original post |
@abby-embree-airship before you adding the dynamic code, do you see an issue with its plan? |
no, but that doesn't mean that the error is indicative of an issue with dynamic blocks rather than the provider - see hashicorp/terraform#28340 |
@abby-embree-airship using below config, I tested apply -> import -> apply on the imported config. No issue is found. What should I do in order for me to repro the issue? From the link you provided, it seems a discussion in the terraform core, not the provider itself. resource "google_compute_security_policy" "policy" {
name = "my-policy"
rule {
action = "deny(403)"
priority = "1000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["9.9.9.0/24"]
}
}
description = "Deny access to IPs in 9.9.9.0/24"
}
rule {
action = "allow"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "default rule"
}
} |
the config you posted won't reproduce the issue because it doesn't create rules via dynamic blocks. the issue i linked indicates that problems with creating dynamic blocks within certain resource types may be indicative of a provider-level issue rather than an hcl-level issue because of how different resource types handle dynamic blocks. I'm working on a complete example to demonstrate this issue, will post when finished |
@rileykarson what do you think about this issue? |
@abby-embree-airship after import, I am able to use below config with a dynamic block to map its state. Do you see anything wrong? locals {
rules = [
{action = "deny(403)", priority = "1000", versioned_expr = "SRC_IPS_V1", src_ip_ranges = ["9.9.9.0/24"], description = "Deny access to IPs in 9.9.9.0/24"},
{ action = "allow", priority = "2147483647", versioned_expr = "SRC_IPS_V1", src_ip_ranges = ["*"], description = "default rule"}
]
}
resource "google_compute_security_policy" "policy" {
name = "issue14178-dynamic"
dynamic "rule" {
for_each = local.rules
content {
action = rule.value.action
priority = rule.value.priority
match {
versioned_expr = rule.value.versioned_expr
config {
src_ip_ranges = rule.value.src_ip_ranges
}
}
description = rule.value.description
}
}
} |
@edwardmedia here's some example code that demonstrates this issue - a less complicated conditional in constructing
do the following:
I think this has something to do with the unusually vague plan output seen below:
again, I think the root of this vagueness has to do with the problem described in hashicorp/terraform#28340 . also, I haven't tested a function call other than timecmp in the for loop creating
|
as for the provider error i posted, i don't remember the exact circumstances that produced that error, but i will work on making it happen again. it's related to this issue somehow, but is tangential to the main problem addressed above |
@abby-embree-airship tried the config from here, I am receiving below error. Does it work for you?
|
@edwardmedia update your terraform version, the timecmp function only exists in terraform 1.3 and later. I used 1.4.0 when writing up this issue. see https://developer.hashicorp.com/terraform/language/functions/timecmp |
@abby-embree-airship I realized the version. After updating it to 1.4.5, it works now. Mind reminding me again about the issue? Applying the config works. After that, plan does not show a diff. What do you want me to look? |
try making the change i mentioned - switch the block_until dates, then re-run the plan. the expected results would be that there would be changes in the plan, the fact that there aren't is a bug. |
@abby-embree-airship I see what you meant now. But if we ignore locals {
blocklist = [
{
ip = "192.0.0.8"
description = "test 1"
# block_until = "1970-01-01T00:00:00Z"
block_until = "2024-01-01T00:00:00Z"
},
{
ip = "8.8.8.8"
description = "test 2"
block_until = "1970-01-01T00:00:00Z"
# block_until = "2024-01-01T00:00:00Z"
}
]
valid_blocks = [
for block in local.blocklist : {
ip = block.ip
description = block.description
}
if timecmp(timestamp(), block.block_until) == -1
]
}
resource "google_compute_security_policy" "this" {
name = "issue14178-user"
dynamic "rule" {
//for_each = local.valid_blocks
for_each = local.blocklist. <------ loop blocklist directly
iterator = block
content {
action = "deny(502)"
priority = block.key
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = [block.value.ip]
}
}
description = block.value.description
}
}
rule {
action = "allow"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
description = "default allow"
}
} |
i believe this to be a provider issue because of what's discussed in hashicorp/terraform#28340, but also because we can test whether this behavior is replicable across different resource types. consider this resource:
when i create it with the blocklist above, then switch around the commented lines and run a plan, i get this:
this tells me the problem isn't with the |
@edwardmedia okay, here's an example of this exact approach working as expected with a different resource type. hopefully this should demonstrate that this issue is specific to this provider and resource type rather than an issue with core terraform:
apply this, then switch the commented out dates, then plan - you will see proposed changes. apply it and you'll see that the authorized networks for the db changes from |
also, i just tested this with a condition other than testing the output of |
Hi @abby-embree-airship 👋 - thanks for your reproduction steps in your previous comment! It helped me familiar with this issue quickly. ProblemI think I've found the underlying cause of the issue - the You can explore this by altering the locals block in your reproduction instructions to use this new locals {
blocklist = [
{
ip = "192.0.0.8"
description = "test 1"
block_until = "2024-01-01T00:00:00Z"
},
{
ip = "8.8.8.8"
description = "test 2"
block_until = "1970-01-01T00:00:00Z"
}
]
current_time = timestamp() # Use when initially applying the config
# current_time = "2023-04-18T00:00:00Z" # 1 in valid_blocks - Uncomment when playing with plans after initial apply
# current_time = "2050-01-01T00:00:00Z" # 0 in valid_blocks - Uncomment when playing with plans after initial apply
# current_time = "1950-01-01T00:00:00Z" # 2 in valid_blocks - Uncomment when playing with plans after initial apply
valid_blocks = [
for block in local.blocklist : {
ip = block.ip
description = block.description
}
if timecmp(local.current_time, block.block_until) == -1
]
} In plan steps (following the initial apply to create the Ideas for next stepsI can see your use case is depending on Terraform to generate a plan to update the
Edit: There is currently a PR in Terraform core to add a specific plan time timestamp! : hashicorp/terraform#32980 In terms of helping you achieve a policy that updates correctly as time passes, one crude option if you are using Terraform OSS is to run CLI commands with a Phew, sorry for writing so much! Please let me know if you have any further questions - I'm happy to discuss this more if needed, but I think we'll eventually close this issue as the problem lies with TF core and not the Google provider |
I tried to work around this by using there are a couple things that i think remain unaddressed: first, this explanation would make sense to me if it only affected the results of a terraform plan, but running a terraform apply also produces no changes - the resource has to be destroyed and recreated to reflect the change made in the local variable, which isn't consistent with the plan vs apply time behavior discussed in the documentation provided. also, the documentation says that a plan that is dependent on the output of that function should get an unknown value that is reflected in the plan, rather than no changes. second, the example i provided in this comment definitively shows that the exact same steps to reproduce, when tried against a different resource type with the same dynamic block pattern, do not result in the behavior demonstrated in the original post. to me this indicates that it's got something to do with that specific resource type, and not a problem with terraform core |
so i was looking through the code a little and it seems like the root of the issue may be this check, which compares the old and new key values provided by https://pkg.go.dev/github.com/hashicorp/terraform/helper/schema#ResourceData.GetChange - a call that happens a few lines above at https://github.com/hashicorp/terraform-provider-google/blob/main/google/resource_compute_security_policy.go#L631 . the issue with doing this comparison is that i believe that
i'm not super confident about all this, but a quick way to check whether i'm on to something or not would be to log the contents of |
Hey, thanks for looking into this. I was doing some similar hunting through the code for a smoking gun yesterday and I found something that might interest you. First I want to acknowledge some of the points you raised above:
Unfortunately the Update/Create/Delete functions are only invoked after a plan has been made identifying that those actions need to be taken on a resource. During the plan stage only Read is invoked, when the state is refreshed. The things relevant to whether a plan is made or not are Terraform core, the SDK, the schema of the resource, and the Read function.
There is currently a project starting to migrate this provider to the plugin framework and there are lot of benefits I'm looking forward to! The SDK is known to have a lot of quirks that the DevEx team has learned from when making this framework. Now, thinking about the different behaviours of dynamic blocks in The reason for this is a quirk of the SDK - it can conflate Computed and Unknown values. I agree that a 'more correct' behaviour for the So the ways to solve this issue seem to be:
I appreciate this is annoying, but I don't think there are any bug fixes that can be made quickly to address this issue. One last thing, a possible way to "make the current timestamp a known value" without waiting on a HashiCorp release is to use a provider that returns the current time as a data source. Data sources are refreshed during plan generation (assuming there are no dependencies with other resources) and are known values. I have toyed with making one on my laptop and I could share it with you if you wish? |
i like this workaround a lot; it doesn't require an external templating tool, and is trivial to set up. the following gets me a nice-looking plan with no known-after-apply values, and catches changes to
and this in
this is a perfectly usable solution until the function you mentioned comes out in 1.5. thanks a ton for your help on this issue @SarahFrench |
Ah the bash script is much simpler than a whole provider, nice! I'm glad we could get your use case working 😄 |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. |
Community Note
modular-magician
user, it is either in the process of being autogenerated, or is planned to be autogenerated soon. If an issue is assigned to a user, that user is claiming responsibility for the issue. If an issue is assigned tohashibot
, a community member has claimed the issue already.Terraform Version
Affected Resource(s)
Terraform Configuration Files
creating a security policy with rules generated via dynamic block does not work as expected; in some cases (i think relating to importing an existing rule then trying to change it vs creating a new one via a terraform apply) i get an error, other times the terraform plan simply shows no changes even when the list the dynamic block is iterating over via for_each changes - create the resource, add an entry to the list used to create rule blocks dynamically, then run a new plan, and you'll see no changes even though you should get a plan that includes adding the new rule block. example tf code:
Error Output
the errors i encountered trying to change the number of rules on an imported resource:
Expected Behavior
changing the content of the list being for_each'ed in the dynamic block should result in planned changes to the resource
Actual Behavior
either nothing happens (erroneously empty plan), or an error like the one above occurs
The text was updated successfully, but these errors were encountered: