Concatenate variables in terraform V0.12 - terraform

I'm trying to update my terraform files from V0.11 to V0.12 and I have some questions.
What's the best way to concatenate variables with strings?
In V0.11 I use this: ${var.name}-STRING-${var.name2}, in V0.12 can I use this: var.name"-STRING-"var.name2 or must I use another ways to concatenate variables and strings?

In v0.12 for interpolations like this:
"${var.example}"
You should use now:
var.example
In your example, In v0.12 you should keep using the previous syntax from v0.11:
"${var.name}-STRING-${var.name2}"
There is a great section in Terraform documentation about migrating to v0.12

To concatenate, check few example below:
If you want to add '#' to string:
value = "${var.username}#${aws_instance.my-instance.public_dns}"
Output: abc#ec2-184-72-11-141.us-west-1.compute.amazonaws.com
To create link:
value = "http://${aws_instance.my-instance.public_dns}:90"
Output: http://ec2-184-72-11-141.us-west-1.compute.amazonaws.com:90

Former C Programmers might like this function better:
format("%s-STRING-%s", var.name, var.name2)
For me, it's less clunky than the old $-Syntax

List of available functions is available at https://www.terraform.io/docs/configuration/functions/join.html
For Python programmers I would suggest using join as another readable alternative:
join("-", [var.name, "STRING", var.name2])

Related

Map Hiera value to another value

How can I achieve something like this in Hiera?
service::enabled: true
plugin:
sensu:
ensure: (if service::enabled: 'present' else 'absent')
I know I can do this with puppet but would like to avoid that.
If you really, really (see below why you don't want to do this) want to have conditional logic in your data, then you could use my tahu::ppyaml() hiera backend which allows you to have puppet logic embedded in the yaml data, or write your own specific backend function. The tahu module requires Puppet 6. For versions of puppet before Hiera 5 you need to write a hiera 3 backend to achieve something similar. With Hiera 5 a backend function is very simple and can even be written in the puppet language.
You can find the tahu::ppayaml function here:
https://github.com/hlindberg/tahu/blob/master/lib/puppet/functions/tahu/ppyaml_key.rb
Your data would then look like this:
service::enabled: true
plugin:
sensu:
ensure: "if $service::enabled { 'present'} else {'absent'}"
Since the ppyaml backend treats every string as puppet language you need to quote all literal strings in the data file read by ppyaml; for example "'foo'" or '"foo"'.
You can however break out the key with a conditional into a separate file and use and alias in your main data file. Like this:
service::enabled: true
plugin:
sensu:
ensure: '%{alias("sensu::ensure")}'
And then, either using the tahu::ppyaml to bind only dynamic keys:
sensu::ensure: if $service::enabled { 'present'} else {'absent'}"
and adding that to your hiera.yaml referencing tahu::ppyaml as a backend.
It would work the same way if you write your own backend.
If any of this is recommended is a different question as it is questionable to have conditional logic in the data that depends on a variable being set or not in a manifest as you will get one value if you do the lookup before the inclusion of sensu and a different value after - and you are probably looking up the hash for the very purpose of declaring sensu.
Unfortunately, Hiera doesn't have expressions that can do anything as sophisticated as conditional logic.
There are some aliasing and lookup functions, so you may be able to pass the value service::enabled through unmodified, but that is it. The functions in Hiera are documented at https://puppet.com/docs/puppet/latest/hiera_merging.html.

How to use markdown in discord.py?

I tried to do it like this:
await message.channel.send("**" + current_text + "**")
But it doesn't work. It will show the result like this:
**
Hey
**
For this, I highly recommend using F-Strings. F-Strings allow you to directly call an variable from a string. This should be easier for you to implement markdown since you can do f"**{current_text}**" and {current_text} will be replaced with the according variable.

How to interpolate expressions in Terraform?

I'm trying to use the keys expression in Terraform to grab a list of keys (from a map variable) and assign it to a local variable. Here is the code snippet:
locals {
project_name_list = keys(${var.project_map})
}
However, I'm getting the following error:
Unknown token: 29:22 IDENT keys
Am I missing something here. Nowhere can I find an example of this expression. As bad as it is, even the official documentation does not help -https://www.terraform.io/docs/configuration/functions/keys.html
HashiCorp has really done a bad job of elaborating the nuances of Terraform for beginners on their website.
Terraform functions need to be wrapped in expression syntax to show that it's not a literal value: "${}"
So try this: project_name_list = "${keys(var.project_map)}"
The example in the documentation is written as though being run from the terraform command line, which already assumes the command is a HCL expression and doesn't require that syntax.
UPDATE
I said above that the expression syntax is to show that it's not a literal value. It's probably more accurate to speak of it as expression syntax vs. configuration syntax. Configuration syntax is the first level of interpolation, which forms the basic structure of your terraform file with resource blocks, data blocks, etc. The second interpolation level is expression syntax which is used to generate values used by your configuration.
Thinking of it in these terms makes better sense of the error message, Unknown token, because terraform is attempting to read it as a configuration key word.
I had compared it to a literal value because it's in the same position as where a literal value would be.

Terraform - embedded quotation marks

In Terraform I can use:
name = "${var.names["apple"])"
which looks up the string "apple" in var.names.
However, this syntax would break in most programming languages as it would try and parse "${var.names[" then apple then "])".
I've looked up documentation on this but failed to find anything. Are there any details?
I've read:
https://www.terraform.io/docs/configuration/syntax.html
and
https://www.terraform.io/docs/configuration/interpolation.html
The last link briefly gives an example
template = "${file("templates/web_init.tpl")}"
but doesn't explain.
Upgrade guide to v0.7 explicitly introduces nested quoting context. Apparently this had been allowed since one of the earlier versions, but I could not pinpoint which one exactly.

Puppet: "latest" vs. latest

Consider the following code:
$version = 'latest'
package { 'mypkg':
ensure => $version;
}
Will this do the same thing as:
package { 'mypkg':
ensure => latest;
}
Yes, those will do the same thing.
Puppet allows simple strings to be unquoted. latest and "latest" are equivalent. Passing a variable that holds the same value is also equivalent.
Note that the style guide only suggests using unquoted bare words in limited circumstances. If there's any question at all, it's better to put single-quotes (') around a string.

Resources