Unable to understand Terraform "interpolation" technique or method - azure

I'm unable to understand what is the issue with the below interpolation for terraform to produce Error out?
resource "azurerm_network_interface" "tf-ni-cluster" {
count = 2
name = "${ax_base_hostname}-ni-${count.index}"
location = "${azurerm_resource_group.tf-rg-cluster.location}"
resource_group_name = "${azurerm_resource_group.tf-rg-cluster.name}"
ip_configuration {
name = "testConfiguration"
subnet_id = "${azurerm_subnet.tf-sn-cluster.id}"
private_ip_address_allocation = "dynamic"
}
}
Error message below:
terraform :
At line:1 char:1
+ terraform plan
+ ~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Error: azurerm_network_interface.tf-ni-cluster: 2 error(s) occurred:
* azurerm_network_interface.tf-ni-cluster[0]: invalid variable syntax: "ax_base_hostname". Did you mean 'var.ax_base_hostname'? If this is part of inline `template`
parameter
then you must escape the interpolation with two dollar signs. For
example: ${a} becomes $${a}.
* azurerm_network_interface.tf-ni-cluster[1]: invalid variable syntax: "ax_base_hostname". Did you mean 'var.ax_base_hostname'? If this is part of inline `template`
parameter
then you must escape the interpolation with two dollar signs. For
example: ${a} becomes $${a}.
Thanks in advance!

Error fixed, it was in error message. Should have used "${var.ax_base_hostname}-${count.index}"

Related

Terraform - How to add port number at the end of a resource name?

Silly question, but struggling to add the port number at the end of a resource for my Terraform build. Here is my resource:
resource "aws_route53_record" "dns_record" {
provider = aws.mgmt
zone_id = data.aws_route53_zone.hosted_zone.zone_id
name = "${var.subdomain}.dev.${data.aws_route53_zone.hosted_zone.name}"
type = "CNAME"
alias {
name = data.aws_elb.test.dns_name:3000
zone_id = data.aws_elb.test.zone_id
evaluate_target_health = true
}
}
I'm trying to add the port at the end of the name under the alias block, but I'm getting this error:
On main.tf line 24: An argument definition must end with a newline.
Which makes me assume this is a syntax error?
How would I be able to manually add the port at the end of the name?
EDIT: Closing this thread because Route53 doesn't handle ports.
It sounds like you are asking how to do string interpolation in HCL2, which would be with the following syntax:
name = "${data.aws_elb.test.dns_name}:3000"

Error while adding tags to vm with powershell after reading from csv

I am trying to add tags to azure vm by reading from csv file with a powershell script. I want to read the value via loop and add to existing tags of vm, if any. Below is my code and the respective errors.
$data = Import-CSV C:\Documents\tags-vms.csv
foreach($info in $data){
$tags = (Get-AzResource -ResourceGroupName policyResourceGroup -Name $info.psobject.properties.value[0]).Tags
$scriptBlock = [scriptblock]::Create('#{$info.Tags}')
$newtags = (& $scriptBlock)
$tags += $newtags
Write-Host $tags
}
Now the error is
Exception calling "Create" with "1" argument(s): "At line:1 char:13
2021-12-20T16:01:09.2145247Z + #{$info.Tags}
2021-12-20T16:01:09.2147301Z + ~
2021-12-20T16:01:09.2149246Z Missing '=' operator after key in hash literal.
2021-12-20T16:01:09.2152282Z At line:1 char:13
2021-12-20T16:01:09.2154454Z + #{$info.Tags}
2021-12-20T16:01:09.2156590Z + ~
2021-12-20T16:01:09.2166796Z The hash literal was incomplete."
2021-12-20T16:01:09.2168854Z At C:\agent\_work\_temp\e8ee61c2-c3f4-4ea5-99ac-4feb671fff57.ps1:18 char:1
2021-12-20T16:01:09.2169842Z + $scriptBlock = [scriptblock]::Create('#{$info.Tags}')
2021-12-20T16:01:09.2170521Z + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2021-12-20T16:01:09.2171329Z + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
2021-12-20T16:01:09.2171826Z + FullyQualifiedErrorId : ParseException
Can someone please help.
**csv file contains**
VmName Tags
test-vm01 "loc"="us"
test-vm02 "Loc"="Us";"doseage"="Second"
I think your issue lies in this line and how you're retrieving the tag info from the CSV object from your foreach loop:
$scriptBlock = [scriptblock]::Create('#{$info.Tags}')
In the previous line in your script, to define the $tags variable, you retrieve the value of the name of the VM in the CSV object using ($info.psobject.properties.value[0]). I would attempt to use that same format in the next line, but modifying it to retrieve the tag part of the CSV object using the index of 1:
So instead of:
$scriptBlock = [scriptblock]::Create('#{$info.Tags}')
use:
$scriptBlock = [scriptblock]::Create('#{$info.psobject.properties.value[1]}')

How to fix "rsadecrypt: argument 1 should be type string, got type list in:"

At the beginning I want to build just one windows machine, so this code works fine at the beginning:
output "Administrator_Password" {
value = "${rsadecrypt(aws_instance.new_instance.password_data, file("${module.ssh_key_pair.private_key_filename}"))}"
}
But once I introduce count to resource "aws_instance" "new_instance" {, I have to add * to the expression aws_instance.new_instance.*.password_data.
But then I start to get this error:
Error: Error running plan: 1 error(s) occurred:
* output.Administrator_Password: At column 3, line 1: rsadecrypt: argument 1 should be type string, got type list in:
${rsadecrypt(aws_instance.new_instance.*.password_data, file("${module.ssh_key_pair.private_key_filename}"))}
I have tried the count.index syntax but they do not work. The variants are
aws_instance.new_instance.password_data[count.index]
and
aws_instance.new_instance.password_data[aws_instance.new_instance.count.index]
Try to use template_file resource,
data "template_file" "decrypted_keys" {
count = "${aws_instance.new_instance.count}"
template = "${rsadecrypt(element(aws_instance.new_instance.*.password_data, count.index), file(module.ssh_key_pair.private_key_filename))}"
}
output "Administrator_Password" {
value = "${data.template_file.decrypted_keys.*.rendered}"
}

Terraform Module - Output error when count = 0

I'm relatively new to Terraform - I have a module setup as below, the issue I'm having is with the outputs if the module count is '0' when running a terraform plan. Output PW works fine now that I've used the element(concat workaround but the Output I'm having issues with is DCPWUn, I get the following error:
Error: Error refreshing state: 1 error(s) occurred:
* module.PrimaryDC.output.DCPWUn: At column 21, line 1: rsadecrypt: argument 1 should be type string, got type list in:
${element(concat("${rsadecrypt(aws_spot_instance_request.PrimaryDC.*.password_data,file("${var.PATH_TO_PRIVATE_KEY}"))}", list("")), 0)}
Code:
resource "aws_spot_instance_request" "PrimaryDC" {
wait_for_fulfillment = true
provisioner "local-exec" {
command = "aws ec2 create-tags --resources ${self.spot_instance_id} --tags Key=Name,Value=${var.ServerName}0${count.index +01}"
}
ami = "ami-629a7405"
spot_price = "0.01"
instance_type = "t2.micro"
count = "${var.count}"
key_name = "${var.KeyPair}"
subnet_id = "${var.Subnet}"
vpc_security_group_ids = ["${var.SecurityGroup}"]
get_password_data = "true"
user_data = <<EOF
<powershell>
Rename-computer -NewName "${var.ServerName}0${count.index +01}"
</powershell>
EOF
tags {
Name = "${var.ServerName}0${count.index +01}"
}
}
output "PW" {
value = "${element(concat("${aws_spot_instance_request.PrimaryDC.*.password_data}", list("")), 0)}"
}
output "DCPWUn" {
value = "${element(concat("${rsadecrypt(aws_spot_instance_request.PrimaryDC.*.password_data,file("${var.PATH_TO_PRIVATE_KEY}"))}", list("")), 0)}"
}
As the error says, rsadecrypt has an argument that is of type list, not string as it should be. If you want to ensure that the argument is a string, you need to invert your function call nesting to make sure that rsadecrypt gets a string:
output "DCPWUn" {
value = "${rsadecrypt(element(concat(aws_spot_instance_request.PrimaryDC.*.password_data, list("")), 0),file("${var.PATH_TO_PRIVATE_KEY}"))}"
}
The problem lies within this line
${element(concat("${rsadecrypt(aws_spot_instance_request.PrimaryDC.*.password_data,file("${var.PATH_TO_PRIVATE_KEY}"))}", list("")), 0)}
What are you trying to achieve? Let's break it down a little
element(…, 0): Get the first element of the following list.
concat(…,list("")): Concatenate the following list of strings and then append the concatenation of a list containing the empty string (Note that the second part is not useful, since you are appending an empty string).
rsadecrypt(…,file("${var.PATH_TO_PRIVATE_KEY}")): decrypt the following expression with the private key (Error: The following thing needs to be a string, you will be supplying a list)
aws_spot_instance_request.PrimaryDC.*.password_data This is a list of all password data (and not a string).
I don't know what your desired output should look like, but with the above list, you may be able to mix-and-match the functions to suit your needs.
edit: Fixed a mistake thanks to the comment by rahuljain1311.

Terraform using count.index in a resource name

using terraform i'm trying to include the count in the name of my resource using count.index, but unable to get the count to display. I'm basically looking to add the count to the resource name so that the resource can be found, otherwise the resource is unknown.
count = 3
autoscaling_group_name = "${aws_autoscaling_group.exampleautoscaling-("count.index")-example.name}"
ERROR
resource variables must be three parts: TYPE.NAME.ATTR in:
expected is : exampleautoscaling-1-example.name,exampleautoscaling-2-example.name,exampleautoscaling-3-example.name
My suggestion will be to add tags and use name_prefix arguments. But specific to your question
Here are some snippets from the documentation what you can try
"${var.hostnames[count.index]}"
OR
resource "aws_instance" "web" {
# ...
count = "${var.count}"
# Tag the instance with a counter starting at 1, ie. web-001
tags {
Name = "${format("web-%03d", count.index + 1)}"
}
}
Providing the link here. Look under the Math section.
Your syntax is incorrect. You are trying to insert count into the middle of a resource name. You need to change it to be the following:
count = 3
autoscaling_group_name = "${aws_autoscaling_group.exampleautoscaling.name}-${count.index}"

Resources