Hi all.
I’m trying to get Terraform to conditionally deploy 4 instances in different AZs in AWS.
resource "aws_instance" "slave02" {
for_each = var.pg_slave02_db_ebs_snapshot_id != "" && terraform.workspace == "prod" ? var.db_subnets : {}
ami = data.aws_ami.ubuntu.id
key_name = aws_key_pair.default_ssh_key[0].key_name
instance_type = var.pg_slave02_instance_type
vpc_security_group_ids = [aws_security_group.database_sg[0].id]
subnet_id = each.value
var.sb_subnets
corresponds to:
# data.tf
data "aws_subnet_ids" "database" {
vpc_id = data.terraform_remote_state.network.outputs.vpc_id
filter {
name = "tag:Name"
values = ["*-db-*"]
}
filter {
name = "tag:Environment"
values = [local.workspace["environment"]]
}
filter {
name = "tag:Terraform"
values = ["true"]
}
}
# main.tf
db_subnets = data.aws_subnet_ids.database.ids
The error that I get is: var.db_subnets is set of string with 3 elements. The true and false result expressions must have consistent types. The given expressions are set of string and object, respectively.
.
Any suggestions are much appreciated.
Instead of {}
use this in your ternary:
var.db_subnets : toset([])
1 Like
Thanks! And how do I reference that resource?
For example:
resource "aws_cloudwatch_metric_alarm" "cw_health_slave02" {
count = var.pg_slave02_db_ebs_snapshot_id != "" && terraform.workspace == "prod" ? 1 : 0
alarm_name = "pgsql-slave02-${terraform.workspace}-StatusCheckFailed"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "1"
metric_name = "StatusCheckFailed"
namespace = "AWS/EC2"
period = "60"
statistic = "Average"
threshold = "1"
alarm_description = "This metric monitors ec2 health status"
alarm_actions = [var.slack_topic_arn]
ok_actions = [var.slack_topic_arn]
dimensions = {
InstanceId = one(aws_instance.slave02[*].id)
}
}
Using InstanceId = [for s in aws_instance.slave02 : s.id]
does not work:
Error: Incorrect attribute value type
│
│ on modules/database/cloudwatch.tf line 53, in resource "aws_cloudwatch_metric_alarm" "cw_health_slave02":
│ 53: dimensions = {
│ 54: InstanceId = [for s in aws_instance.slave02 : s.id]
│ 55: }
│ ├────────────────
│ │ aws_instance.slave02 is object with 3 attributes
│
│ Inappropriate value for attribute "dimensions": element "InstanceId": string required.
Using InstanceId = [for s in aws_instance.slave02 : s.id][0]
Interesting! It works, thanks for your help!
Glad to help. Btw. Its the same syntax used in python or javascript to access the entry of a list (python) or an array (javascript) using the position, starting at 0.
Yep… thanks!
Unfortunately the part where I deploy each instance in a different AZ is not working.
subnet_id = each.value
availability_zone = "ap-southeast-1a"
Error is:
Value (ap-southeast-1a) for parameter availabilityZone is invalid. Subnet 'subnet-08f561963ceb6467f' is in the availability zone ap-southeast-1b
Do you have any suggestions there?
I’ve opened a new issue for this last question: Aws_instance with specific AZ - #2 by lpossamai