I am working with a resource ( google_monitoring_uptime_check_config) which only allows one of these blocks to be present.
Either http_check or tcp_check.
I tried setting them both up as a dynamic block, but the terraform plan sees them both as being there, and gives this error.
Error: "tcp_check": only one of
http_check,tcp_check can be specified, but
http_check,tcp_check were specified.
If you leave both out, you get this error.
Error: "tcp_check": one of
http_check,tcp_check must be specified
How can I build one module, which will complete only the block I need?
Can you copy/paste the âdynamic blockâ attempt you made?
Hi @kpfleming, sorry I donât have that code any longer. When it did not work I moved on.
I do have another idea which I read about today. It it works I will post it here.
I found a clue in another post on this site. The answer is to define 2 resources in the same file, and use a boolean and a count as a conditional to build one or the other resource.
I will include the code here so hopefully it will help someone else that comes across this issue.
main .tf file
locals {
monitored_resource_labels = {
uptime_url = {
project_id = var.project_id
host = var.host
}
gce_instance = {
project_id = var.project_id
instance_id = var.instance_id
zone = var.zone
}
gae_app = {
project_id = var.project_id
module_id = var.module_id
version_id = var.version_id
zone = var.zone
}
}
}
# This resource builds a http based uptime check
resource "google_monitoring_uptime_check_config" "uptime_check_https" {
count = var.is_http_check ? 1 : 0
display_name = var.display_name
timeout = var.timeout
period = var.period
selected_regions = var.selected_regions
http_check {
path = var.path
port = var.port
use_ssl = var.use_ssl
validate_ssl = var.validate_ssl
headers = var.headers
mask_headers = var.mask_headers
}
monitored_resource {
type = var.type
labels = local.monitored_resource_labels[var.type]
}
content_matchers {
content = var.content
}
}
# This resource builds a tcp based uptime check
resource "google_monitoring_uptime_check_config" "uptime_check_tcp" {
count = var.is_tcp_check ? 1 : 0
display_name = var.display_name
timeout = var.timeout
period = var.period
selected_regions = var.selected_regions
tcp_check {
port = var.tcp_port
}
monitored_resource {
type = var.type
labels = local.monitored_resource_labels[var.type]
}
content_matchers {
content = var.content
}
}
Extract from vars.tf file
# This module handles both HTTP(S) and TCP uptime checks
# ONE and ONLY ONE of these two boolean variables MUST be set to true.
variable "is_http_check" {
type = bool
default = false
description = "(Required) Is this uptime check a HTTP(S) type request"
}
variable "is_tcp_check" {
type = bool
default = false
description = "(Required) Is this uptime check a TCP type request"
}
1 Like
Hi @mwohlin,
What you originally tried with dynamic
blocks should be possible as long as the for_each
expression in the dynamic blocks is derived only from values that can be known during the plan phase. That is, either constant values or references to constant values elsewhere, and to any resource result attributes that the provider is able to predict during planning.
A problem arises whenever the for_each
expression is derived from something that isnât predictable during planning. These are values that would be marked with the placeholder (known after apply)
in the rendered plan. If Terraform canât know the exact length of the collection given in for_each
then it will pessimistically assume that the length is at least one and perform validation under that assumption.
Since you werenât able to share the original configuration you tried I canât offer any advice specific to it, but hopefully this information is useful for if you encounter a similar situation in future.
(Itâs also possible for there to be provider-specific validation bugs that might affect the behavior Iâm describing here in some cases, but I donât think thatâs true in this case: the error text you reported looks like the standard âconflicting argumentsâ reporting thatâs part of the shared validation code in the Terraform SDK, common to all providers.)
2 Likes
@apparentlymart Thank you for the insight and all of your help with this. I suspected something as such was going on. That is very useful information which I will remember.
I am happy with the current configuration and I feel it is easy for users to understand.