Key Vault Secret Time Expiry - azure

I am trying to set an expiry date that is dynamic in a Terraform template. The idea is to get current date and add 6 months to that date and use that as the expiry date for the secret, however I am struggling to do so.
I am trying to achieve this using the time_offset and timestamp() but it isn't working and I get the following error.
main.tf
resource "time_offset" "expiry_date" {
offset_months = 6
}
resource "azurerm_key_vault_secret" "local_admin_pwd" {
name = "LocalAdminPassword"
value = random_password.pwd.result
key_vault_id = azurerm_key_vault.keyvault.id
expiration_date = timestamp(time_offset.expiry_date.rfc3339)
}
error
│ Error: Too many function arguments
│
│ on key_vault/main.tf line 56, in resource "azurerm_key_vault_secret" "local_admin_pwd":
│ 56: expiration_date = timestamp(time_offset.expiry_date.rfc3339)
│ ├────────────────
│ │ while calling timestamp()
│
│ Function "timestamp" expects only 0 argument(s).

The built-in timestamp function does not expect any arguments:
Function "timestamp" expects only 0 argument(s).
The expiration_date argument should get the value from the attribute provided by the time_offset resource only:
expiration_date = time_offset.expiry_date.rfc3339

Related

Can I use for_each meta-argument with file function?

I am creating a bunch of random strings using resource_string resource block.
length is a required argument for this resource, and my goal is to read all the values for this variable from a file, using the file function.
Is there a way to do it?
Here is my code, along with the error:
resource "random_string" "any_string" {
for_each = toset(file("string_number_file.txt"))
length = each.key
}
cat string_number_file.txt
"10","12","13"
Goal is to create three random_strings, with above lengths.
Here is the error with above code:
Error: Invalid function argument
│
│ on main.tf line 9, in resource "random_string" "any_string":
│ 9: for_each = toset(file("string_number_file.txt"))
│
│ Invalid value for "v" parameter: cannot convert string to set of any single type.
Thanks in advance!
In that case you can convert your file to json, and then use that:
resource "random_string" "any_string" {
for_each = toset(jsondecode(format("[%s]",file("string_number_file.txt"))))
length = each.key
}

Reference Variable inside Module

I am trying to reference a variable declared inside a module to update another variable in the same module and i am unable to find a guide as to how i can reference the variable.
Here is my code sippet
module "cluster" {
source = "..."
var1 = value1 # directly passing value
var2 = module.cluster.var1 # I need to update this variable value based on value of var1
I am facing below error during terraform plan
Terraform v1.0.11
on linux_amd64
Configuring remote state backend...
Initializing Terraform configuration...
Error: Unsupported attribute
│
│ on main.tf line 04, in module "cluster":
│ 04: var2 = module.cluster.var1
│ ├────────────────
│ │ module.cluster is a object, known only after apply
│
│ This object does not have an attribute named "var1".
I have also tried using referencing using local.var1 shown below
module "cluster" {
source = "..."
var1 = value1 # directly passing value
var2 = local.var1 # I need to update this variable value based on value of var1
and then i encounter below error
Terraform v1.0.11
on linux_amd64
Configuring remote state backend...
Initializing Terraform configuration...
╷
│ Error: Reference to undeclared local value
│
│ on main.tf line 04, in module "cluster":
│ 04: var2 = local.var1
│
│ A local value with the name "var1" has not been declared.
╵
any lead will be helpful.
Regards
Your second attempt, using a local variable, is on the right track, but you have to actually declare the local variable:
locals {
var1 = value1
}
module "cluster" {
source = "..."
var1 = local.var1
var2 = local.var1

How to create string output with splat operator in terraform

I am creating several count - based ELBs with terraform.
e.g.
resource "aws_elb" "webserver_example" {
count = var.create_webserver
name = var.name
subnets = data.aws_subnet_ids.default.ids
security_groups = [aws_security_group.elb[count.index].id]
}
I therefore want to be able to get as outputs their http endpoints.
These outputs I assume shoul be strings, and their should somehow incorporate each elb's dns name.
However the following approach using splat, does not work
output "url" {
value = "http://${aws_elb.webserver_example.*.dns_name}:${var.elb_port}"
}
│ Error: Invalid template interpolation value
│
│ on outputs.tf line 2, in output "url":
│ 2: value = "http://${aws_elb.webserver_example.*.dns_name}:${var.elb_port}"
│ ├────────────────
│ │ aws_elb.webserver_example is empty tuple
│
│ Cannot include the given value in a string template: string required.
╵
Is there a way to print multiple count-based strings?
From what I was able to infer from just the code you provided, your var.create_webserver will have different count values (e.g. >= 0). The answer to your specific question is in this code block:
output "url" {
value = [
for dns_name in aws_elb.webserver_example.*.dns_name :
format("http://%s:%s", dns_name, var.elb_port)
]
}
However, be sure you introduce some way to make the names of your Security Groups and ELBs different, because that will be your next error. For example, name = "${var.name}-${count.index}".
Once you get to that point, you will have output that looks like this:
Outputs:
url = [
"http://so-0-2118247212.us-east-1.elb.amazonaws.com:443",
"http://so-1-1137510015.us-east-1.elb.amazonaws.com:443",
]

Can we change something in child modules ".terraform/modules"?

When I run terraform plan I got the following errors:
Error: Reference to undeclared input variable
│
│ on .terraform/modules/ec2-datapipeline/main.tf line 5, in resource "aws_instance" "this":
│ 5: count = "${var.count}"
│
│ An input variable with the name "count" has not been declared. This
│ variable can be declared with a variable "count" {} block.
╵
╷
│ Error: Incorrect attribute value type
│
│ on .terraform/modules/ec2-datapipeline/main.tf line 13, in resource "aws_instance" "this":
│ 13: vpc_security_group_ids = ["${var.vpc_security_group_ids}"]
│ ├────────────────
│ │ var.vpc_security_group_ids is a list of string, known only after apply
│
│ Inappropriate value for attribute "vpc_security_group_ids": element 0:
│ string required.
╵
╷
│ Error: Unsupported argument
│
│ on .terraform/modules/ec2-datapipeline/main.tf line 23, in resource "aws_instance" "this":
│ 23: root_block_device = "${var.root_block_device}"
│
│ An argument named "root_block_device" is not expected here. Did you mean to
│ define a block of type "root_block_device"?
╵
╷
│ Error: Unsupported argument
│
│ on .terraform/modules/ec2-datapipeline/main.tf line 24, in resource "aws_instance" "this":
│ 24: ebs_block_device = "${var.ebs_block_device}"
│
│ An argument named "ebs_block_device" is not expected here. Did you mean to
│ define a block of type "ebs_block_device"?
╵
╷
│ Error: Unsupported argument
│
│ on .terraform/modules/ec2-datapipeline/main.tf line 25, in resource "aws_instance" "this":
│ 25: ephemeral_block_device = "${var.ephemeral_block_device}"
│
│ An argument named "ephemeral_block_device" is not expected here. Did you
│ mean to define a block of type "ephemeral_block_device"?
╵
╷
│ Error: Error in function call
│
│ on .terraform/modules/ec2-datapipeline/main.tf line 36, in resource "aws_instance" "this":
│ 36: tags = "${merge(var.tags, map("Name", format("%s-%d", var.name, count.index+1)))}"
│ ├────────────────
│ │ count.index is a number, known only after apply
│ │ var.name will be known only after apply
│
│ Call to function "map" failed: the "map" function was deprecated in
│ Terraform v0.12 and is no longer available; use tomap({ ... }) syntax to
│ write a literal map.
When I fixed them in .terraform/modules/main.tf and variables.tf files, plan was successful and it went through when I trigger from CLI. But, when I actually push the code when I trigger a plan from UI it doesn't work.
So, when I do terraform init --upgrade. It came back to normal and I can see the same issues.
Could you please help me in solving this? thanks!
The stuff in .terraform/modules/ec2-datapipeline/main.tf is actually the main.tf file from an external module called "ec2-datapipeline" referenced somewhere in your own code (look for module "ec2-datapipeline").
You have to fix the bug in the source for "ec2-datapipeline", commit and tag it, then update the source reference in your own code.
The reason your changes disappear on reinitialization is, that you passed the --upgrade switch which tells Terraform to redownload the external module sources, even if they are cached locally in the .terraform/modules cache.

what's causing terraform error: Call to function "formatlist" failed: error on format iteration 0: unsupported value for "%s" at 5: string required

In my terraform code I have the following locals
locals {
merged_acl_contributors = concat(var.workspace.acl.contributors, azurerm_synapse_workspace.workspace.identity)
contributors = formatlist("user:%s:rwx", local.merged_acl_contributors)
}
var.workspace.acl.contributors does not have a value (just has []). When I try to deploy this I get:
│ Error: Error in function call
│
│ on modules/synapse_v2/main.tf line 10, in locals:
│ 10: contributors = formatlist("user:%s:rwx", local.merged_acl_contributors)
│ ├────────────────
│ │ local.merged_acl_contributors is tuple with 1 element
│
│ Call to function "formatlist" failed: error on format iteration 0:
│ unsupported value for "%s" at 5: string required.
identity in azurerm_synapse_workspace.workspace is a block with multiple attributes. You have to choose what you want. For example:
merged_acl_contributors = concat(var.workspace.acl.contributors, [azurerm_synapse_workspace.workspace.identity.principal_id])
Looking at local.merged_acl_contributors was the answer. The value was wrong. Instead of azurerm_synapse_workspace.identity, it needed to be azurerm_synapse_workspace.managedidentity.

Resources