I want to read a list of objects from a yaml file via terraform code and map it to a local variable. Also i need search an object with a key and get the values from a yaml file. Can anyone suggest suitable solution?
my yaml file looks like below. Here use will be the primary key
list_details:
some_list:
- use: a
path: somepath
description : "some description"
- use: b
path: somepath2
description : "some description 2"
I have loaded the yaml file in my variable section in Terraform like this
locals {
list = yamldecode(file("${path.module}/mylist.yaml"))
}
Now the problem is how I can get one object with its values by passing the "use" value to the list?
"
Assuming that use values are unique, you can re-organize your list into map:
locals {
list_as_map = {for val in local.list["list_details"]["some_list"]:
val["use"] => val["path"]}
}
which gives list_as_map as:
"a" = "somepath"
"b" = "somepath2"
then you access the path based on a value of use:
path_for_a = local.list_as_map["a"]
Update
If you want to keep description, its better to do:
list_as_map = {for val in local.list["list_details"]["some_list"]:
val["use"] => {
path = val["path"]
description = val["description"]
}
}
then you access the path or description as:
local.list_as_map["a"].path
local.list_as_map["a"].description
Related
I would like to define a List of Strings in .yaml config (ss is attached).
For example: ['HNN','FRC']
I've created sth like that.
self.argParser.add_argument(
'--source.prefiks.list',
nargs = '*',
required=False,
default="",
help='Param used for definition of selected procesess')
I'm ok with this approach: It works properly.
self.argParser.add_argument(
'--source.prefiks.list',
type = lambda s: [str(item) for item in s.split(',')],
required=False,
help='Param used for definition of selected procesess')
This question already has answers here:
How to pass terraform outputs variables into ansible as vars_files?
(5 answers)
Closed 2 years ago.
I followed the answer here in this question and
I have created a template file tf_ansible_vars_file.yml.tpl like below
tf_share_location: "${share_location}"
and a terra_render.tf like below
# Define an Ansible var_file containing Terraform variable values
data "template_file" "tf_ansible_vars_file" {
template = "${file("/home/deployment_root/app4/tf_ansible_vars_file.yml.tpl")}"
vars = {
share_location = var.share_location
# gitlab_backup_bucket_name = aws_s3_bucket.gitlab_backup.bucket
}
}
# Render the Ansible var_file containing Terrarorm variable values
resource "local_file" "tf_ansible_vars_file" {
content = data.template_file.tf_ansible_vars_file.rendered
filename = "/home/deployment_root/app4/tf_ansible_vars_file.yml"
}
I already have a variables.tf file in which i have declared that variable
variable "share_location" {
type = string
}
and in the terraform.tfvars gave the value as null
share_location = null
when i run terraform apply i get the below error
Error: failed to render : <template_file>:1,23-37: Unknown variable; There is no variable named "share_location".
on terra_render.tf line 2, in data "template_file" "tf_ansible_vars_file":
2: data "template_file" "tf_ansible_vars_file" {
My understanding is it will create a file as mentioned in that answer, but it is not working.
How do you output variables to Ansible?
If you are generating a supported format like YAML, you do not need a template file.
You can generate YAML directly from Terraform data structures as follows:
resource "local_file" "tf_ansible_vars_file" {
content = yamlencode(
{
tf_share_location = var.share_location
# gitlab_backup_bucket_name = aws_s3_bucket.gitlab_backup.
}
)
filename = var.ansible_vars_filename
}
variable "ansible_vars_filename" {
type = string
default = "/home/deployment_root/app4/tf_ansible_vars_file.yml"
}
Applying that with -var="share_location=example_location" will yield a file like this:
"tf_share_location": "example_location"
Whether or not the quoting the configuration variable names matters depends on Ansible. It shouldn't as it's still valid YAML. Terraform's yamlencode quotes those regardless of whether they need to be, which is regrettable.
I have extracted ansible_vars_filename to a variable as you may want to make that configurable.
I have also left in the commented out gitlab_backup_bucket_name as adding it to the YAML file is as simple as uncommenting it.
You can learn more about yamlencode here:
https://www.terraform.io/docs/configuration/functions/yamlencode.html
In the below code, instead of var.share_location , i need to give the variable that i used in terraform in my case
${data.azurerm_storage_account.new.name}/sharename and after that i can remove that from variables.tf as well as terraform.tfvars as i am getting the value generated. Thanks
Old code :
data "template_file" "tf_ansible_vars_file" {
template = "${file("/home/deployment_root/app4/tf_ansible_vars_file.yml.tpl")}"
vars = {
share_location = var.share_location
# gitlab_backup_bucket_name = aws_s3_bucket.gitlab_backup.bucket
}
}
New Code:
# Define an Ansible var_file containing Terraform variable values
data "template_file" "tf_ansible_vars_file" {
template = "${file("/home/deployment_root/app4/tf_ansible_vars_file.yml.tpl")}"
vars = {
share_location = "${data.azurerm_storage_account.new.name}/sharename"
# gitlab_backup_bucket_name = aws_s3_bucket.gitlab_backup.bucket
}
}
I need to use a variable as a part of a string that will be used to address another variable in a gstring.
In syntesys, what I'd like to do is: ${${it}_checkout}
The whole code line would be:
def checkouts = repos.collect{"${it} = ${${it}_checkout} "}
With repos being a list of repositories to checkout.
Each repo has an property called <repo>_checkout.
For instance, if I have two repos, called foo and bar, I'll have two variables called foo_checkout and bar_checkout, containing the branches to be checkouted.
I'm trying to construct the following string: "foo=$foo_checkout bar=$bar_checkout".
That will be translated to "foo=master bar=dev"
Is there a way ?
Yeh, just do:
def checkouts = repos.collect{ "$it = ${it}_checkout" }
Or, depending on how you declare your properties, you can do:
root_checkout = 'woo'
repo_checkout = 'yay'
['root', 'repo'].collect { r -> "$r = ${getProperty(r + '_checkout')}" }
I have a text file (objects.txt) which contains Objects and its attributes.
The content of the file is something like:
Object.attribute = "data"
On a different file, I am Loading the objects.txt file and if I type:
puts object.attribute it prints out data
The issue comes when I am trying to access the object and/or the attribute with a string. What I am doing is:
var = "object" + "." + "access"
puts var
It prints out object.access and not the content of it "data".
I have already tried with instance_variable_get and it works, but I have to modify the object.txt and append an # at the beginning to make it an instance variable, but I cannot do this, because I am not the owner of the object.txt file.
As a workaround I can parse the object.txt file and get the data that I need but I don't want to do this, as I want take advantage of what is already there.
Any suggestions?
Yes, puts is correctly spitting out "object.access" because you are creating that string exactly.
In order to evaluate a string as if it were ruby code, you need to use eval()
eg:
var = "object" + "." + "access"
puts eval(var)
=> "data"
Be aware that doing this is quite dangerous if you are evaluating anything that potentially comes from another user.
Hi I've a puppet template with below values.
myfile.erb
name = "abc"
desg = "engineer"
Sal = "10000"
And I try to read these values from my puppet script like below
init.pp
$value = template("d:/puppet/modules/mymodule/templates/myfile.erb")
now my $value is containing all values from the myfile.erb file. Is there any way to divide the values like $value[0], $value[1] etc..
I want to display only "abc" "engineer" "1000"
When your data lookup starts getting complicated, I highly recommend you move away from templates towards an external data lookup, like hiera. For a guide to setting up, I've written a small tutorial here. You can substitute yaml for json.
Your hiera file could look as simple as this:
{
"myfile": {
"name": "abc",
"desg": "engineer"
"Sal": "10000"
}
}
And then in your file:
$vars = hiera('myfile')
// Gives "abc"
$vars['name']
// Gives "engineer"
$vars['desg']