Terraform map(object) variable in BitBucket Pipelines - terraform

I am deploying Terraform code through a Bitbucket pipeline and am having an problem when parsing a map of objects variable in the pipeline. Below is the variable:
variable "images" {
type = map(object({
port = number
}))
}
Below is how the variable value is defined in the BitBucket Pipeline variables:
"{"image_one"={port=1000}"image_two"={port=2000}}"
When the pipeline runs, I am getting the following error:
Error: Extra characters after expression
│
│ on <value for var.images> line 1:
│ (source code not available)
│
│ An expression was successfully parsed, but extra characters were found
│ after it.
Below is the command within bitbucket-pipelines.yml on how the variable is called within the pipeline:
terraform apply -var images="$IMAGES" -auto-approve
Any advice on how to get the map of objects to execute through the pipeline would be helpful.
Thank you.

Assuming that this is your actual code, and not again some mistake you did when making the question, then you are missing a comma between arguments. It should be:
"{"image_one"={port=1000}, "image_two"={port=2000}}"

Related

Issue in importing Azure resource into Terraform state

Objective: Trying to import module.resource which is already created azure resource via terraform into my statefile
What I tried:
terraform -chdir=Terraform import synapse_workspace_pe.azurerm_private_endpoint.syn_ws_pe_dev "/subscriptions/xxxx-xxxx-xxx--xx/resourceGroups/hub/providers/Microsoft.Network/privateEndpoints/pe-cb-ab-dev-we-dev"
Error that I get:
error: Invalid address
│
│ on <import-address> line 1:
│ 1: synapse_workspace_pe.azurerm_private_endpoint.syn_ws_pe_dev
│
│ Resource instance key must be given in square brackets
I referred to some stackoverflow posts, syntax is same. can some one tell me how to fix this ?
When importing resources from a declared module, then the namespace must be prefixed with the string literal module:
terraform -chdir=Terraform import module.synapse_workspace_pe.azurerm_private_endpoint.syn_ws_pe_dev "/subscriptions/xxxx-xxxx-xxx--xx/resourceGroups/hub/providers/Microsoft.Network/privateEndpoints/pe-cb-ab-dev-we-dev"

Terraform plan not recognizing argument in terraform cloud in certain environment

I am trying to add the attribute "response_headers_policy" to the aws_cloudfront_distribution module. I have 3 environments: prod, stage, demo. Prod was the first created, followed by stage and demo a few months later. When adding that attribute to the staging and demo environments, there are no issues. However the plan fails with the following error when running for the prod environment:
Error: Unsupported argument
│
│ on ../../modules/<module>/cloudfront.tf line 47, in resource "aws_cloudfront_distribution" "this":
│ 47: response_headers_policy_id = "67f7725c-6f97-4210-82d7-5512b31e9d03" // SecurityHeadersPolicy ID
│
│ An argument named "response_headers_policy_id" is not expected here.
My assumption is that the state file expects an older version of the module for the production environment, but I am unsure how to resolve that issue. Especially in terraform cloud.
My first thought is that there is a mismatch in what version of the AWS provider you're using for your different environments. That argument was only added to the AWS provider in v3.64.0, in #21620.

Terraform Output doesn't exist after running terraform apply

I configure my terraform using a GCS backend, with a workspace. My CI environment exactly has access to the state file it requires for the workspace.
terraform {
required_version = ">= 0.14"
backend "gcs" {
prefix = "<my prefix>"
bucket = "<my bucket>"
credentials = "credentials.json"
}
}
I define the output of my terraform module inside output.tf:
output "base_api_url" {
description = "Base url for the deployed cloud run service"
value = google_cloud_run_service.api.status[0].url
}
My CI Server runs terraform apply -auto-approve -lock-timeout 15m. It succeeds and it shows me the output in the console logs:
Outputs:
base_api_url = "https://<my project url>.run.app"
When I call terraform output base_api_url and it gives me the following error:
│ Warning: No outputs found
│
│ The state file either has no outputs defined, or all the defined outputs
│ are empty. Please define an output in your configuration with the `output`
│ keyword and run `terraform refresh` for it to become available. If you are
│ using interpolation, please verify the interpolated value is not empty. You
│ can use the `terraform console` command to assist.
I try calling terraform refresh like it mentions in the warning and it tells me:
╷
│ Warning: Empty or non-existent state
│
│ There are currently no remote objects tracked in the state, so there is
│ nothing to refresh.
╵
I'm not sure what to do. I'm calling terraform output RIGHT after I call apply, but it's still giving me no outputs. What am I doing wrong?
I had the exact same issue, and this was happening because I was running terraform commands from a different path than the one I was at.
terraform -chdir="another/path" apply
And then running the output command would fail with that error. Unless you cd to that path before running the output command.
cd "another/path"
terraform output

Terraform rename a resource without deleting

I created AzDo repositories using the Terraform. But what is the best way to rename the repository without deleting it. I found a command "terraform state mv" for the purpose. Please let me know if there is a better way.
Currently when I use the Terraform state mv command I'm getting below error
terraform state mv "module.azdo-module.azuredevops_git_repository[\"repo1\"]" "module.azdo-module.azuredevops_project.azuredevops_git_repository[\"repo2\"]"
Getting below error
Error: Invalid address
│
│ on line 1:
│ (source code not available)
│
│ A resource name is required.
maybe
terraform state mv "module.azdo-module.azuredevops_git_repository.repo1" "module.azdo-module.azuredevops_project.azuredevops_git_repository.repo2"
list resources to check the name
terraform state list
Terraform has introduced a new declarative way to refactor resources with the move block syntax in 1.1 version.
Steps:
rename the resource to the new name
moved {
from = module.azdo-module.azuredevops_git_repository.repo1
to = module.azdo-module.azuredevops_project.azuredevops_git_repository.repo2
}
update references to a new resource name
plan and apply
remove the moved block (given no one else is using your modules)
More info:
https://developer.hashicorp.com/terraform/language/modules/develop/refactoring#moved-block-syntax

Terraform - Use of environment variables in TF files

I would like to use environment variables in my TF files. How can I mention them in those files?
I use Terraform cloud and define the variables in the environment variables section. Which means I don't use my cli to run terraform commands commands (no export TF_VAR & no -var or -var-file parameter).
I didn’t find any answer to this in forums nor in documentation.
Edit:
Maybe if I'll elaborate the things I've done it will be much clear.
So I have 2 environment variables named "username" and "password"
Those variables are defined in the environment variables section in Terraform Cloud.
In my main.tf file I create a mongo cluster which should be created with those username and password variables.
In the main variables.tf file I defined those variables as:
variable "username" {
type = string
}
variable "password" {
type = string
}
My main.tf file looks like:
module "eu-west-1-mongo-cluster" {
...
...
username = var.username
password = var.password
}
In the mongo submodule I defined them in variables.tf file as type string and in the mongo.tf file in the submodule I ref them as var.username and var.password
Thanks !
I don't think what you are trying to do is supported by Terraform Cloud. You are setting Environment Variables in the UI but you need to set Terraform Variables (see screenshot).
For Terraform Cloud backend you need to dynamically create *.auto.tfvars, none of the usual -var="myvar=123" or TF_VAR_myvar=123 or terraform.tfvars are currently supported from the remote backend. The error message below is produced from the CLI when running terraform 1.0.1 with a -var value:
│ Error: Run variables are currently not supported
│
│ The "remote" backend does not support setting run variables at this time. Currently the
│ only to way to pass variables to the remote backend is by creating a '*.auto.tfvars'
│ variables file. This file will automatically be loaded by the "remote" backend when the
│ workspace is configured to use Terraform v0.10.0 or later.
│
│ Additionally you can also set variables on the workspace in the web UI:
│ https://app.terraform.io/app/<org>/<workspace>/variables
My use case is in a CI/CD pipeline with the CLI using a remote Terraform Cloud backend, so created the *.auto.tfvars with for example:
# Environment variables set by pipeline
TF_VAR_cloudfront_origin_path="/mypath"
# Dynamically create *.auto.tfvars from environment variables
cat >dev.auto.tfvars <<EOL
cloudfront_origin_path="$TF_VAR_cloudfront_origin_path"
EOL
# Plan the run
terraform plan
As per https://www.terraform.io/docs/cloud/workspaces/variables.html#environment-variables, terraform will export all the provided variables.
So if you have defined an environment variable TF_VAR_name then you should be able to use as var.name in the terraform code.
Hope this helps.
I managed to get around this in my devops pipeline, by copying the terraform.tfvars file from my sub directory to the working directory as file.auto.tfvars
For example:
cp $(System.DefaultWorkingDirectory)/_demo/env/dev/variables.tfvars $(System.DefaultWorkingDirectory)/demo/variables.auto.tfvars

Resources