Terraform variable error : The given value is not valid - google-cloud-platform

I am trying to create a monitoring alert policy using terraform. But in the plan stage i am getting the below error on the variable. Has anyone faced a similar issue in the past ? I am new to terraform and i can trying to create a iterable resource for monitoring alert policy in gcp.
Error: Invalid value for input variable
│
│ on terraform.tfvars line 149:
│ 149: alert_policies = {
│ 150: "composer_alert" = {
│ 151: combiner = "OR"
│ 152: display_name = "Alert Strategy"
│ 153: enabled = "true"
│ 154: conditions = [
│ 155: {display_name = "Bytes used condition"
│ 156: conditions_threshold = {
│ 157: "1" = {
│ 158: comparison = "COMPARISON_GT"
│ 159: duration = "0s"
│ 160: filter = "resource.type = \"cloud_composer_environment\" AND resource.labels.project_id = \"prj-comp-01\" AND metric.type = \"composer.googleapis.com/environment/database/disk/bytes_used\""
│ 161: threshold_value = 1600000000
│ 162: alignment_period = "300s"
│ 163: cross_series_reducer = "REDUCE_NONE"
│ 164: group_by_fields = ["project_id"]
│ 165: per_series_aligner = "ALIGN_MEAN"
│ 166: trigger_count = 1
│ 167: trigger_percent = 100
│ 168: }
│ 169: }
│ 170: }
│ 171: ]
│ 172: notification_channels = [
│ 173: "projects/prj-test-01/notificationChannels/2276385315451985010"
│ 174: ]
│ 175: }
│ 176: }
│
│ The given value is not valid for variable "alert_policies": a number is
│ required.
╵
╷
│ Error: Incorrect variable type
│
│ on variables.tf line 392:
│ 392: variable "alert_policies" {
│
│ The resolved value of variable "alert_policies" is not appropriate: a
│ number is required.
Variables.tf****
variable "alert_policies" {
type = map(object({
combiner = optional(string)
display_name = optional(string)
enabled = optional(bool)
uptime_checks = optional(map(object({
duration = number
uptime_check_name = string
ssl_expiry_checks = optional(list(object({
days_left = number
})))
})))
conditions = list(object({
display_name = string
conditions_threshold = map(object({
comparison = string
duration = number
filter = string
threshold_value = number
alignment_period = number
cross_series_reducer = string
group_by_fields = list(string)
per_series_aligner = string
trigger_count = number
trigger_percent = number
}))
notification_channels = optional(list(string))
}))
}))
}
╵

Related

is there a way to concatenate multiple list variables in terraform locals

i have 2 string list variables.
["domain1", "domain2"]
["log1", "log2", "log3"]
I need to concatenate these list like this:
"log-name/domain1/log1"
"log-name/domain1/log2"
"log-name/domain1/log3"
"log-name/domain2/log1"
"log-name/domain2/log2"
"log-name/domain2/log3"
variable domain_names {
type=list(object({
domain_name = string
elasticsearch_version = number
}))
}
variable log_names {
type = list(string)
default = [ "log1", "log2", "log3" ]
}
locals {
log_template = [
for d in var.domain_names : [
for l in var.log_names : {
log = "log-name/${var.domain_names[d].domain_name}/${var.log_names[l]}"
}
]
]
}
and my terraform.tfvars:
domain_names = [
{
domain_name = "domain1"
elasticsearch_version = "6.8"
},
{
domain_name = "domain2"
elasticsearch_version = "6.8"
}, ]
when i apply this terraform code, i am getting this error:
Error: Invalid index
│
│ on elasticsearch_domain.tf line 99, in locals:
│ 99: log = "log-name/${var.domain_names[d].domain_name}/${var.log_names[l]}"
│ ├────────────────
│ │ var.domain_names is list of object with 1 element
│
│ The given key does not identify an element in this collection value: number required.
╵
╷
│ Error: Invalid index
│
│ on elasticsearch_domain.tf line 99, in locals:
│ 99: log = "log-name/${var.domain_names[d].domain_name}/${var.log_names[l]}"
│ ├────────────────
│ │ var.log_names is list of string with 4 elements
│
│ The given key does not identify an element in this collection value: a number is required.
what are the best practices for it? how can i concat these and use them in one resource like this:
resource "aws_cloudwatch_log_group" "log-groups" {
name = ...
}
You can use flatten and the following new version of your for loop to get your desired list:
locals {
log_template = flatten([
for d in var.domain_names : [
for l in var.log_names : [
"log-name/${d.domain_name}/${l}"
]
]
])
}

read_replicas_mode & replica_count variables are not expected in google_redis_instance

We have used the memory store module for spinning up a redis instance on GCP. However, at a later stage, when we try to enable READ REPLICA via terraform it doesn't accept.
References:
https://github.com/terraform-google-modules/terraform-google-memorystore
module "memorystore_replica" {
source = "terraform-google-modules/memorystore/google"
version = "4.0.0"
redis_version = "REDIS_6_X"
name = "${module.project.project_name}-redisreadreplica-${module.locations.region_codes[var.region]}-instance"
project = module.project.project_id
region = var.region
authorized_network = local.vpc
connect_mode = var.redis_connection_type
memory_size_gb = var.redis_memory_size_gb
transit_encryption_mode = "DISABLED"
labels = var.labels
replica_count = 2
read_replicas_mode = "READ_REPLICAS_ENABLED"
}
resource "google_redis_instance" "default" {
depends_on = [module.enable_apis]
project = var.project
name = var.name
tier = var.tier
memory_size_gb = var.memory_size_gb
connect_mode = var.connect_mode
region = var.region
location_id = var.location_id
alternative_location_id = var.alternative_location_id
authorized_network = var.authorized_network
redis_version = var.redis_version
redis_configs = var.redis_configs
display_name = var.display_name
reserved_ip_range = var.reserved_ip_range
labels = var.labels
auth_enabled = var.auth_enabled
transit_encryption_mode = var.transit_encryption_mode
}
Error: Unsupported argument
│
│ on main.tf line 357, in module "memorystore_replica":
│ 357: replica_count = 2
│
│ An argument named "replica_count" is not expected here.
╵
╷
│ Error: Unsupported argument
│
│ on main.tf line 358, in module "memorystore_replica":
│ 358: read_replicas_mode = "READ_REPLICAS_ENABLED"
│
│ An argument named "read_replicas_mode" is not expected here
Any help appreciated!

terraform missing resource instance key,issue with for_each

resource "aws_sqs_queue" "CloudTrail_SQS"{
for_each = var.sqs_queue_names
name = each.value
visibility_timeout_seconds = var.visibility_timeout_seconds
max_message_size = var.max_message_size
message_retention_seconds = var.message_retention_seconds
delay_seconds = var.delay_seconds
receive_wait_time_seconds = var.receive_wait_time_seconds
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.CloudTrail_SQS_DLQ[each.key].arn
maxReceiveCount = var.max_receive_count
})
tags = var.default_tags
}
resource "aws_sqs_queue" "CloudTrail_SQS_DLQ"{
for_each = var.dead_queue_names
name = each.value
visibility_timeout_seconds = var.visibility_timeout_seconds
max_message_size = var.max_message_size
message_retention_seconds = var.message_retention_seconds
delay_seconds = var.delay_seconds
receive_wait_time_seconds = var.receive_wait_time_seconds
tags = var.default_tags
}
resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy" {
queue_url = aws_sqs_queue.CloudTrail_SQS[each.key].id
My terragrunt plan returns this. it complains about for_each and when i try to fix that i get another errror, but unsure what to do with it:
1.....Error: Missing resource instance key
│
│ on iam.tf line 2, in resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy":
│ 2: queue_url = aws_sqs_queue.CloudTrail_SQS.id
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ aws_sqs_queue.CloudTrail_SQS[each.key]
2...Error: Missing resource instance key
│
│ on iam.tf line 14, in resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy":
│ 14: "Resource": "${aws_sqs_queue.CloudTrail_SQS.arn}",
│
│ Because aws_sqs_queue.CloudTrail_SQS has "for_each" set, its attributes
│ must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ aws_sqs_queue.CloudTrail_SQS[each.key]
3.........
Error: Reference to "each" in context without for_each
│
│ on iam.tf line 27, in resource "aws_sqs_queue_policy" "CloudTrail_SQS_DLQ":
│ 27: queue_url = aws_sqs_queue.CloudTrail_SQS_DLQ[each.key].id
│
│ The "each" object can be used only in "module" or "resource" blocks, and
│ only when the "for_each" argument is set.
There is no for_each in your Cloudtrail_SQS_Policy. Thus you can't use each.key.
Guess it should be:
resource "aws_sqs_queue_policy" "Cloudtrail_SQS_Policy" {
for_each = var.dead_queue_names
queue_url = aws_sqs_queue.CloudTrail_SQS[each.key].id

Terraform workspaces creation

I am trying to write a terraform code for creating workspaces and will be using the same for future creation as well. I am facing an issue while referencing the bundle_ids since there are multiple bundles available and it changes according to the req. each time. if someone can suggest a better approach to this.
resource "aws_workspaces_workspace" "this" {
directory_id = var.directory_id
for_each = var.workspace_user_names
user_name = each.key
bundle_id = [local.bundle_ids["${each.value}"]]
root_volume_encryption_enabled = true
user_volume_encryption_enabled = true
volume_encryption_key = var.volume_encryption_key
workspace_properties {
user_volume_size_gib = 50
root_volume_size_gib = 80
running_mode = "AUTO_STOP"
running_mode_auto_stop_timeout_in_minutes = 60
}
tags = var.tags
}
terraform.tfvars
directory_id = "d-xxxxxxx"
##Add the Workspace Username & bundle_id;
workspace_user_names = {
"User1" = "n"
"User2" = "y"
"User3" = "k"
}
locals.tf
locals {
bundle_ids = {
"n" = "wsb-nn"
"y" = "wsb-yy"
"k" = "wsb-kk"
}
}
Terraform plan
Error: Incorrect attribute value type
│
│ on r_aws_workspaces.tf line 8, in resource "aws_workspaces_workspace" "this":
│ 8: bundle_id = [local.bundle_ids["${each.value}"]]
│ ├────────────────
│ │ each.value will be known only after apply
│ │ local.bundle_ids is object with 3 attributes
│
│ Inappropriate value for attribute "bundle_id": string required.
At the movement you have a list, but it should be string. Assuming everything else is correct, the following should address your error:
bundle_id = local.bundle_ids[each.value]

Handling empty value in for_each and assign default value terraform

I am creating aws_workspace, In this terraform I am looping over the variables provided in the main file and assigning the values using for each loop. But the issue that I am facing is that I am trying to pass the username only as a second variable and now I am trying that for-each loop should pick the default value if the value is not given from the main.tf file but its not working. like it should pick the second username and append other values by default with it
main.tf
module "aws_workspace" {
source = "./modules/aws_workspace"
aws_workspace = {
user1 = {
user_name = "john.doe"
root_volume_encryption_enabled = true
user_volume_encryption_enabled = true
volume_encryption_key = "alias/aws/workspaces"
compute_type_name = "VALUE"
user_volume_size_gib = 10
root_volume_size_gib = 80
running_mode = "AUTO_STOP"
running_mode_auto_stop_timeout_in_minutes = 60
},
user2 = {
user_name = "james"
}
}
tags = {
Name = "cloud"
}
bundle_id = data.aws_workspaces_bundle.value_windows_10.id
directory_id = aws_workspaces_directory.example.id
}
variable.tf
variable "aws_workspace" {
default = [
{
root_volume_encryption_enabled = true
user_volume_encryption_enabled = true
volume_encryption_key = "alias/aws/workspaces"
compute_type_name = "VALUE"
user_volume_size_gib = 10
root_volume_size_gib = 80
running_mode = "AUTO_STOP"
running_mode_auto_stop_timeout_in_minutes = 60
}
]
description = "configuration of aws workspaces"
}
variable "tags" {
default = ""
description = "tags of the resources"
}
variable "directory_id" {
default = ""
description = "Id of the directory"
}
variable "bundle_id" {
default = ""
description = "id of the bundle"
}
resource.tf
resource "aws_workspaces_workspace" "example" {
directory_id = var.directory_id
bundle_id = var.bundle_id
for_each = var.aws_workspace
user_name = each.value.user_name
root_volume_encryption_enabled = each.value.root_volume_encryption_enabled
user_volume_encryption_enabled = each.value.user_volume_encryption_enabled
volume_encryption_key = each.value.volume_encryption_key
workspace_properties {
compute_type_name = each.value.compute_type_name
user_volume_size_gib = each.value.user_volume_size_gib
root_volume_size_gib = each.value.root_volume_size_gib
running_mode = each.value.running_mode
running_mode_auto_stop_timeout_in_minutes = each.value.running_mode_auto_stop_timeout_in_minutes
}
tags = var.tags
}
Error:
╷
│ Error: Unsupported attribute
│
│ on modules/aws_workspace/main.tf line 9, in resource "aws_workspaces_workspace" "example":
│ 9: root_volume_encryption_enabled = each.value.root_volume_encryption_enabled
│ ├────────────────
│ │ each.value is object with 1 attribute "user_name"
│
│ This object does not have an attribute named "root_volume_encryption_enabled".
╵
╷
│ Error: Unsupported attribute
│
│ on modules/aws_workspace/main.tf line 10, in resource "aws_workspaces_workspace" "example":
│ 10: user_volume_encryption_enabled = each.value.user_volume_encryption_enabled
│ ├────────────────
│ │ each.value is object with 1 attribute "user_name"
│
│ This object does not have an attribute named "user_volume_encryption_enabled".
╵
╷
│ Error: Unsupported attribute
│
│ on modules/aws_workspace/main.tf line 11, in resource "aws_workspaces_workspace" "example":
│ 11: volume_encryption_key = each.value.volume_encryption_key
│ ├────────────────
│ │ each.value is object with 1 attribute "user_name"
│
│ This object does not have an attribute named "volume_encryption_key".
╵
╷
│ Error: Unsupported attribute
│
│ on modules/aws_workspace/main.tf line 14, in resource "aws_workspaces_workspace" "example":
│ 14: compute_type_name = each.value.compute_type_name
│ ├────────────────
│ │ each.value is object with 1 attribute "user_name"
│
│ This object does not have an attribute named "compute_type_name".
╵
╷
│ Error: Unsupported attribute
│
│ on modules/aws_workspace/main.tf line 15, in resource "aws_workspaces_workspace" "example":
│ 15: user_volume_size_gib = each.value.user_volume_size_gib
│ ├────────────────
│ │ each.value is object with 1 attribute "user_name"
│
│ This object does not have an attribute named "user_volume_size_gib".
╵
╷
│ Error: Unsupported attribute
│
│ on modules/aws_workspace/main.tf line 16, in resource "aws_workspaces_workspace" "example":
│ 16: root_volume_size_gib = each.value.root_volume_size_gib
│ ├────────────────
│ │ each.value is object with 1 attribute "user_name"
│
│ This object does not have an attribute named "root_volume_size_gib".
╵
╷
│ Error: Unsupported attribute
│
│ on modules/aws_workspace/main.tf line 17, in resource "aws_workspaces_workspace" "example":
│ 17: running_mode = each.value.running_mode
│ ├────────────────
│ │ each.value is object with 1 attribute "user_name"
│
│ This object does not have an attribute named "running_mode".
╵
╷
│ Error: Unsupported attribute
│
│ on modules/aws_workspace/main.tf line 18, in resource "aws_workspaces_workspace" "example":
│ 18: running_mode_auto_stop_timeout_in_minutes = each.value.running_mode_auto_stop_timeout_in_minutes
│ ├────────────────
│ │ each.value is object with 1 attribute "user_name"
│
│ This object does not have an attribute named "running_mode_auto_stop_timeout_in_minutes".
You have to change your design a bit, so that default values are outside of variable. For example:
variable "aws_workspace" {
default = {
user1 = {
user_name = "john.doe"
root_volume_encryption_enabled = true
user_volume_encryption_enabled = true
volume_encryption_key = "alias/aws/workspaces"
compute_type_name = "VALUE"
user_volume_size_gib = 10
root_volume_size_gib = 80
running_mode = "AUTO_STOP"
running_mode_auto_stop_timeout_in_minutes = 60
},
user2 = {
user_name = "james"
}
}
description = "configuration of aws workspaces"
}
locals {
my_defaults = {
root_volume_encryption_enabled = true
user_volume_encryption_enabled = true
volume_encryption_key = "alias/aws/workspaces"
compute_type_name = "VALUE"
user_volume_size_gib = 10
root_volume_size_gib = 80
running_mode = "AUTO_STOP"
running_mode_auto_stop_timeout_in_minutes = 60
}
final_aws_workspace = {for k,v in var.aws_workspace:
k => merge(local.my_defaults, v)
}
}
Then you can use :
for_each = var.final_aws_workspace