I would like to retrieve separately the key and value from Vault using Terraform.
For the following try, I am receiving that the value doesn't exists.
data "vault_generic_secret" "kv" {
path = "kv/test"
}
output "kv" {
value = "${data.vault_generic_secret.kv.data["Value"]}"
}
For an output as follows, I am getting the Key + Value in the following format: "key/value".
output "kv" {
value = "${data.vault_generic_secret.kv.data}"
}
It's any way to retrieve just the key and just the value separately?
Thanks
Related
I am trying to use Terraform function lookup and then lookup to fetch the values and then add into the conditional loop based on the value like below - For creating s3 bucket server side encryption
Below is var.tf
variable "encryption" {
type = map
default = {
"keyMap" = "SSE-S3"
"kmsType" = "aws-kms"
"keyNull" = null
}
}
Now I want to use local.tf with below code to get "SSE-S3" value like below
encryption_type = lookup(var.encryption, "default", null) == null ? null : lookup(var.encryption.default, "keyMap", null)
Just wonder above my logic will fetch the value for encryption_type is "SSE-S3"
Any help is appreciated. Thanks in advance.
You don't have to lookup "default". The default inside a variable definitions is just the default value of that variable. Your current code is actually invalid because a lookup on "default" is never going to work. It's also not clear what your "keyMap" lookup is doing, since there is no property in your example named "keyMap".
Your code could be corrected and shortened to the following:
encryption_type = lookup(var.encryption, "keyType", null)
or just
encryption_type = var.encryption["keyType"]
I'm writing a module to create multiple S3 Buckets with all the related resources. Currently, I'm a little bit stuck on the server side encryption as I need to parametrize the KMS key id for a key that is not still created.
The variables passed to the module are:
A list of S3 buckets
A map with the KMS created
The structure of the S3 buckets is
type = list(object({
bucket = string
acl = string
versioning = string
kms_description = string
logging = bool
loggingBucket = optional(string)
logPath = optional(string)
}))
}
The structure of the KMS map is similar to
kms_resources = {
0 = {
kms_arn = (known after apply)
kms_description = "my-kms"
kms_id = (known after apply)
}
}
This variable is an output from a previous module that creates all the KMS. The output is created this way
output "kms_resources" {
value = {
for kms, details in aws_kms_key.my-kms :
kms => ({
"kms_description" = details.description
"kms_id" = details.key_id
"kms_arn" = details.arn
})
}
}
As you can see the idea is that, on the S3 variable, the user can select his own KMS key, but I'm struggling to retrieve the value. At this moment, resource looks like this
resource "aws_s3_bucket_server_side_encryption_configuration" "my-s3-buckets" {
count = length(var.s3_buckets)
bucket = var.s3_buckets[count.index].bucket
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = [
for k in var.kms_keys : k.kms_id
if k.kms_description == var.s3_buckets[count.index].kms_description
]
sse_algorithm = "aws:kms"
}
}
}
I thought it was gonna work but once terraform is giving me Inappropriate value for attribute "kms_master_key_id": string required.. I would also like that if the value does not exist the kms_master_key_id is set by default to aws/s3
The problem seems to be that you try to give a list as kms_master_key_id instead of just a string. The fact that you alternatively want to use "aws/s3" actually makes the fix quite easy:
kms_master_key_id = concat([
for k in var.kms_keys : k.kms_id
if k.kms_description == var.s3_buckets[count.index].kms_description
], ["aws/s3"])[0]
That way you first get a list with keys / that key that matches the description and then append the default s3 key. Afterwards you simply pick the first element of the list, either the first actual key or if none matched you pick the default key.
I am building a kafka streams topology in which I need to materialize the contents of a Global KTable in a persistent RocksDB store. This store will be further used on every instance of my application for querying.
The store consinsts of key values pairs, where the key is serialized using Avro and the payload is just a byte array.
My problem is when I try to query the store by a specific key, as shown in the code below:
fun topology() {
val streamsBuilder = StreamsBuilder()
streamsBuilder.globalTable<Key, ByteArray>(
SOURCE_TOPIC_FOR_GLOBAL_KTABLE,
Consumed.with(null /*Uses default serde provided in config which is SpecificAvroSerde*/,
Serdes.ByteArray()),
Materialized.`as`(STORE_NAME))
val kafkaStreams = KafkaStreams(streamsBuilder.build(), getProperties(), DefaultKafkaClientSupplier())
kafkaStreams.start()
}
private fun getProperties(): Properties {
val properties = Properties()
properties[StreamsConfig.BOOTSTRAP_SERVERS_CONFIG] = "kafka-brokers-ip"
properties[AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG] = "schema-registry-ip"
properties[StreamsConfig.APPLICATION_ID_CONFIG] = "app-id"
properties[ConsumerConfig.CLIENT_ID_CONFIG] = "client-id"
properties[ConsumerConfig.AUTO_OFFSET_RESET_CONFIG] = "earliest"
properties[StreamsConfig.STATE_DIR_CONFIG] = "C:/dev/kafka-streams"
properties[StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG] = SpecificAvroSerde::class.java
properties[StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG] = SpecificAvroSerde::class.java
return properties
}
And this is the function that I use to query the store:
val store = kafkaStreams
.store(STORE_NAME, QueryableStoreTypes.keyValueStore<Key, ByteArray>())
store.all().forEach { keyValue ->
if (keyValue.key == Key("25-OCT-19 USD")) {
//we get here, so the key is in the store
println("Keys are equal.")
println(keyValue) // this gets printed: KeyValue({"value": "25-OCT-19 USD"}, [B#3ca343b5)
println(store.get(Key("25-OCT-19 USD"))) //this is null
println(store.get(keyValue.key)) //this is also null
}
}
As you can see in the comments of code, there are values in the store, but when I try to query by a specific key, I get nothing back.
I want to automate deployments of Vmware VM's in an landscape with lots of portgroups. To be able to select the correct portgroup it would be best to enter 2 variables tenant and environment. These 2 variables are used for CMDB registration and deployment purposes.
For the deployment the variables need to be combined in to 1 new variable to pick the correct portgroup. Due to interpolation syntax it seems to be impossible to use 2 combined variables in the lookup.
How can I combine 2 variables to 1 in Terraform?
I also tried to make a local file with the correct string, but that file needs to exist before the script starts, terraform plan gives a error message that the file doesn't exist.
variable "tenant" {
description = "tenant: T1 or T2"
}
variable "environment" {
description = "environment: PROD or TEST"
}
variable "vm_network" {
description = "network the VM will be provisioned with"
type = "map"
default = {
T1_PROD = "T1-PROD-network"
T2_PROD = "T2-PROD-network"
T1_TEST = "T1-TEST-network"
T2_TEST = "T2-TEST-network"
}
}
data "vsphere_network" "network" {
name = "${lookup(var.vm_network, tenant_environment)}"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
Off the top of my head I can think of three different ways to merge the variables to use as a lookup key:
variable "tenant" {}
variable "environment" {}
variable "vm_network" {
default = {
T1_PROD = "T1-PROD-network"
T2_PROD = "T2-PROD-network"
T1_TEST = "T1-TEST-network"
T2_TEST = "T2-TEST-network"
}
}
locals {
tenant_environment = "${var.tenant}_${var.environment}"
}
output "local_network" {
value = "${lookup(var.vm_network, local.tenant_environment)}"
}
output "format_network" {
value = "${lookup(var.vm_network, format("%s_%s", var.tenant, var.environment))}"
}
output "lookup_network" {
value = "${lookup(var.vm_network, "${var.tenant}_${var.environment}")}"
}
The first option uses locals to create a variable that is interpolated already and can be easily reused in multiple places which can't be done directly with variables in Terraform/HCL. This is generally the best way to do variable combination/interpolation in later versions of Terraform (they were introduced in Terraform 0.10.3).
The second option uses the format function to create a string containing the tenant and environment variables.
The last one is a little funny looking but is valid HCL. I'd probably shy away from using that syntax if possible.
I'm trying to query a dojo datastore object. The store has multiple objects, each one as a key titled OBJECTID with a unique value. Is there a way to query the store like this:
dataStoreObjet.query({OBJECTID : 6990, OBJECTID: 34277, OBJECTID: 9501 } );
Right now it only returns the last object. I'm sure I'm missing something simple, but it is driving me bonkers. I don't want to have to run a query for each value and then create a new set of values from all those queries if I don't have to.
Thanks
The object {OBJECTID : 6990, OBJECTID: 34277, OBJECTID: 9501 } will only contain one value that of the last one.
This is because a javascript object is a map of properties and its value.
The {OBJECTID : 6990, OBJECTID: 34277, OBJECTID: 9501 } definition is same as
var obj = { OBJECTID : 6990 };
obj.OBJECTID = 34277;
obj.OBJECTID = 9501;
As you can see from the above the obj object contains the last value i.e 9501. In effect your query to the dataStoreObjet
is
dataStoreObjet.query({OBJECTID : 9501} );
Now the solution to your problem.
You need to pass a function as a query parameter that will compare the values and return true or false for the objects to be part of the query result.
dataStoreObjet.query( function(object){
return (object.OBJECTID == 6990) || (object.OBJECTID == 6990) || (object.OBJECTID == 6990) ;
}) // Pass a function to do more complex querying