How to append string and variable in terraform - terraform

How can I concatenate string and a variable in terraform. I am using terraform version 1.7
Name = "Test (Environment_Name)" where environment_name will be test,stage and prod.
resource "fusionauth_tenant" "tanant" {
name = "Test (Environment_name)"
email_configuration {
default_from_name = "FusionAuth [Environment_name]"
verification_email_template_id = fusionauth_email.verification_template.id
}

Examples of how to append a string and a variable.
settings.tf:
locals {
bucket_prefix = "test-bucket"
}
And then you want to create three S3 buckets.
s3.tf:
resource "aws_s3_bucket" "a" {
bucket = "${local.bucket_prefix}-app"
}
//name = test-bucket-app
resource "aws_s3_bucket" "b" {
bucket = local.bucket_prefix
}
//name = test-bucket
resource "aws_s3_bucket" "c" {
bucket = "my-bucket"
}
//name = my-bucket
If you want to append a variable from var or get a name from a resource, it will follow the same pattern. It will always be:
"${var.name.value}-my-string"

Related

How to add value(s) to an object from Terraform jsondecode without copying values over to another variable?

I have a following example of Terraform resources where I fetch values from secrets manager and pass them to the Lambda function. The question is how can I add extra values to an object before passing it to environment variable without replicating the values?
resource "aws_secretsmanager_secret" "example" {
name = "example"
}
resource "aws_secretsmanager_secret_version" "example" {
secret_id = aws_secretsmanager_secret.example.id
secret_string = <<EOF
{
"FOO": "bar"
}
EOF
}
data "aws_secretsmanager_secret_version" "example" {
secret_id = aws_secretsmanager_secret.example.id
depends_on = [aws_secretsmanager_secret_version.example]
}
locals {
original_secrets = jsondecode(
data.aws_secretsmanager_secret_version.example.secret_string
)
}
resource "aws_lambda_function" "example" {
...
environment {
variables = local.original_secrets
}
}
As a pseudo code I'd like to do something like this:
local.original_secrets["LOG_LEVEL"] = "debug"
The current approach I have is just to replicate the original values and add a new but of course this is not DRY.
locals {
...
updated_secrets = {
FOO = try(local.original_secrets.FOO, "")
DEBUG = "false"
}
}
You can use Terraform merge function to produce new combined map of environment variables.
lambda_environment_variables = merge(local.lambda_secrets, local.environment_variables)

Create a S3 bucket on each AWS account created with terraform

I am using terraform to create multiple AWS accounts using aws_organizations_account. What I am now trying to do is to create a aws_S3_bucket on each new created accounts.
resource "aws_organizations_account" "this" {
for_each = local.all_user_ids
name = "Dev Sandbox ${each.value}"
email = "${var.manager}+sbx_${each.value}#example.com"
role_name = "Administrator"
parent_id = var.sandbox_organizational_unit_id
}
resource "aws_s3_bucket" "b" {
bucket = "my-tf-test-bucket"
acl = "private"
}
Everything is working as expected for aws_organizations_account during my terraform apply but my S3 bucket is created inside my current AWS project while I am trying to create a S3 bucket for every new AWS account.
Step 1: Create_terraform_s3_buckets.tf
# First configure the AWS Provider
provider "aws" {
access_key = var.aws_access_key
secret_key = var.aws_secret_key
region = var.aws_region
}
// then use the resource block and create all the buckets in the variable array
// Here setup your accounts would in the variable for e.g. My_Accounts_s3_buckets
variable "My_Accounts_s3_buckets" {
type = list
default = ["Testbucket1.app", "Testbucket2.app", "Testbucket3.app"]
}
Look up the s3_bucket objectfor more help from Terraform ref. aws_s3_bucket
// resource "aws_s3_bucket" "rugged_buckets" "log_bucket" { <- different types of options on your buckets
resource "aws_s3_bucket" "b" {
count = length(var.My_Accounts_s3_buckets) // here are you 3 accounts
bucket = var.My_Accounts_s3_buckets[count.index]
acl = "private"
region = "us-east-1"
force_destroy = true
tags = {
Name = "My Test bucket"
Environment = "Dev"
}
}
Step 2: You can now automate this with the variables file.
# Make sure you keep this order
variable "My_Accounts_s3_buckets" {
type = list
default = ["mybucket1.app",
"mybucket2.app" // you can add more.. as needed
]
}

Use for_each to create multiple disks and their snapshots using a list input

I am writing TF code to create multiple disks in GCP. The aim is to have dry code and have a list as an input.
My var app_disks has the following definition
variable "app_disks" {
type = list(object({
name = string
size = number
}))
}
And in my main.tf, im using the variable like this
app_disks = [
{
name = loki
size = 200
},
{
name = repo
size = 100
}
]
And in my module, my disk.tf looks like this
locals {
app_disk_map = {
for disk in var.app_disks : "${disk.name}" => disk
}
}
resource "google_compute_resource_policy" "app_disk_backup" {
for_each = local.app_disk_map
name = "${each.value.name}-backup"
snapshot_schedule_policy {
schedule {
hourly_schedule {
hours_in_cycle = 8
start_time = "04:00"
}
}
retention_policy {
max_retention_days = 14
on_source_disk_delete = "APPLY_RETENTION_POLICY"
}
}
}
resource "google_compute_disk" "app_disk" {
for_each = local.app_disk_map
provider = google-beta
name = each.value.name
zone = "${var.region}-a"
size = each.value.size
resource_policies = [each.google_compute_resource_policy.app_disk_backup[${each.value.name}-backup].self_link]
}
What im not sure about it how to link the resource_policies of the disk to its relevant google_compute_resource_policy".
Ive tried combinations like
each.google_compute_resource_policy.app_disk_backup[${each.value.name}-backup].self_link
each.google_compute_resource_policy.app_disk_backup."${each.value.name}-backup".self_link
But none seem to be working
I am not completely sure if I get the problem right (as an error output is missing), but from what I understood you want to have the following reference: google_compute_resource_policy.app_disk_backup[each.key].self_link so the resource would look something like:
resource "google_compute_disk" "app_disk" {
for_each = local.app_disk_map
....
resource_policies = [google_compute_resource_policy.app_disk_backup[each.key].self_link]
}
this will reference the same key that was used to create the dependent resource and create a 1:1 mapping between dependencies.

Can I Pass Terraform output / resources.id values into any variable present in variable.tf file?

I need to have "client_secret" output value as an input for "tenant_app_password"
variables.tf
variable "tenant_app_password" {
description = ""
}
Create-service-principal.tf
resource "random_string" "password" {
length = 32
special = true
}
# Create Service Principal Password
resource "azuread_service_principal_password" "test_sp_pwd" {
service_principal_id = azuread_service_principal.test_sp.id
value = random_string.password.result
end_date = "2020-01-12T07:10:53+00:00"
}
OUTPUT
output "client_secret" {
value = "${azuread_service_principal_password.wvd_sp_pwd.value}"
sensitive = true
}
Is we have any possible way ???
I'm assuming you want to use the output of one Terraform run in another one. You can do this by using a remote state datasource provider.
You cannot put the original output in a variable, but you can use the remote output as a variable directly in another template. For example, in your second template:
// set up the remote state data source
data "terraform_remote_state" "foo" {
backend = "s3"
config = {
bucket = "<your bucket name>"
key = "<your statefile name.tfstate"
region = "<your region>"
}
}
// use it
resource "kubernetes_secret" "bar" {
metadata {
name = "bar"
}
data = {
client_secret = data.terraform_remote_state.foo.outputs.client_secret
}
}
Also check out this question.

Terraform outputs for resources with count

I have my s3 resource in terraform with configuration:
locals {
bucket_count = "${length(var.s3_config["bucket_names"])}"
}
resource "aws_s3_bucket" "s3_bucket" {
count = "${local.bucket_count}"
bucket = "${format("%s-%s", element(var.s3_config["bucket_names"], count.index), var.region)}"
acl = "private"
region = "${var.region}"
tags {
Name = "${format("%s-%s", element(var.s3_config["bucket_names"], count.index), var.region)}"
}
}
and i want to set output variable for all created bucket so i created file names outputs.tf with content
output "buckets" {
value = "${aws_s3_bucket.s3_bucket.*.bucket}"
}
output "buckets_arns" {
value = "${aws_s3_bucket.s3_bucket.*.arn}"
}
when i apply configuration its ok i see outputs in terraform.tfstate file but when i call terraform output i see information that is no output or output is empty what i do wrong ?
Try this:
output "buckets" {
value = ["${aws_s3_bucket.s3_bucket.*.bucket}"]
}
output "buckets_arns" {
value = ["${aws_s3_bucket.s3_bucket.*.arn}"]
}

Resources