json file in terraform - terraform

I have a JSON file with the following and trying to list the shapes ex: "t3-nano, t3-micro, t3-small, t2.medium, t3-2xlarge, r6g-medium".
json file = info.json
{
"t3-nano" : {
"service_name" : "t3",
"existing" : 100
},
"t3-micro" : {
"service_name" : "t3",
"existing" : 1
},
"t3-small" : {
"service_name" : "t3",
"existing" : 2
},
"t2.medium" : {
"service_name" : "t2",
"existing" : 0
},
"t3-2xlarge" : {
"service_name" : "t3-2",
"existing" : 5
},
"r6g-medium" : {
"service_name" : "r6g.medium",
"existing" : 10
}
}
I tried the following
locals {
service_name = flatten([for i in local.info : i[*].service_name])
shapes = flatten([for i in local.info : i[*].index])
}
and it got failed
Error: Unsupported attribute
This object does not have an attribute named "index".
I was expecting to print shapes = [t3-nano, t3-micro, t3-small, t2.medium, t3-2xlarge, r6g-medium]. Can someone help if there is a way to just list the shapes?

The flatten function and for expression are both unnecessary here. The function keys already has the functionality and return value that you want to achieve:
shapes = keys(local.info)
and that will assign the requested value.

Related

Combine list and object in terraform

How do I combine something like
[for x in var.variable : { "key" : x , "value" : true}]
and
{ "key" : "*", "value" : true}
Say var.variable is an array/list with values [1,2]
and then I need to perform a jsonencode on the above result in terraform.
I have tried merge, join, concat but somehow nothing seems to work or maybe I dont know how to use them correctly.
I need the final output something like -
[
{
"key" : 1,
"value" : true
},
{
"key" : 2,
"value" : true
},
{
"key" : "*",
"value" : true
},
]
You can do that as follows:
variable "variable" {
default = [1,2]
}
output "test" {
value = jsonencode(concat(
[for x in var.variable : { "key" : x , "value" : true}],
[{ "key" : "*", "value" : true}]))
}

print from json with a given condition in terraform

I'm into the terraform world recently and learning based on the requirements. I've a question on printing the values with a given condition
json file:
{
"team1" : [
{
"engg_name" : "Alex",
"guid" : 1001,
"scope" : "QA"
},
{
"engg_name" : "Trex",
"guid" : 1002,
"scope" : "QA"
},
{
"engg_name" : "Jessica",
"guid" : 1003,
"scope" : "QA"
},
{
"engg_name" : "Tom",
"guid" : 1004,
"scope" : "DEV"
}
],
"team2" : [
{
"engg_name" : "Roger",
"guid" : 2001,
"scope" : "DEV"
},
{
"engg_name" : "Jhonny",
"guid" : 2002,
"scope" : "DEV"
}
]
}
What I'm trying:
print the engg whose scope is DEV from the json file
locals {
teams = jsondecode(file("${path.module}/teams_info.json"))
engg_with_scope_dev = flatten([for i in local.teams : i.teams if keys(local.teams).scope == "DEV"])
}
Error:
engg_with_scope_dev = flatten([for i in local.teams : i.teams if keys(local.teams).scope == "DEV"])
|----------------
| local.teams is object with 2 attributes
This value does not have any attributes.
Can someone suggest me what's the right way to just print based on the condition?
output must be as following:
engg_with_scope_dev = ["Tom", "Roger", "Jhonny"]
You need an embedded for loop for this:
locals {
teams = jsondecode(file("${path.module}/teams_info.json"))
engg_with_scope_dev = flatten([for team in local.teams : [
for engineer in team : engineer.engg_name if engineer.scope == "DEV"
]])
}
Other solution would be to use a concatenation of the lists with ellipsis operator:
locals {
teams = jsondecode(file("${path.module}/teams_info.json"))
engg_with_scope_dev = ([
for engineer in concat(values(local.teams)...) : engineer.engg_name if engineer.scope == "DEV"
])
}
But also, a simple flatten with values would work as well:
locals {
teams = jsondecode(file("${path.module}/teams_info.json"))
engg_with_scope_dev = ([
for engineer in flatten(values(local.teams)) : engineer.engg_name if engineer.scope == "DEV"
])
}

Terraform nested objects transformation

I'm working on a module and I have a variable structure like the following:
input = [
{
"prod_db" : {...someOtherAttributes}
"prod_app": {...someOtherAttributes}
},
{
"stage_db" : {...someOtherAttributes}
"stage_app": {...someOtherAttributes}
},
{
"dev_db" : {...someOtherAttributes}
"dev_app": {...someOtherAttributes}
}
]
is there a way to have a map of only the second-level object? something like this:
result = {
"prod_db" : {...someOtherAttributes},
"prod_app": {...someOtherAttributes},
"stage_db" : {...someOtherAttributes},
"stage_app": {...someOtherAttributes},
"dev_db" : {...someOtherAttributes},
"dev_app": {...someOtherAttributes}
}
Your expected result is invalid data structure. I guess that you actually want the following:
result = merge(var.input...)
Where ... is for Expanding Function Arguments.

Unable to set _id on elasticsearch-hadoop

I am trying to write from an rdd to elasticsearch (pyspark, python 3.5).
I am capable of writing the body of the json correctly but elasticsearch instead of taking my _id, it creates it's own.
My code:
class Article:
def __init__(self, title, text, text2):
self.id_ = title
self.text = text
self.text2 = text2
if __name__ == '__main__':
pt=_sc.parallelize([Article("rt", "ted", "ted2"),Article("rt2", "ted2", "ted22")])
save=pt.map(lambda item:
(item.id_,
{
'text' : item.text,
'text2' : item.text2
}
))
es_write_conf = {
"es.nodes": "localhost",
"es.port": "9200",
"es.resource": 'db/table1'
}
save.saveAsNewAPIHadoopFile(
path='-',
outputFormatClass="org.elasticsearch.hadoop.mr.EsOutputFormat",
keyClass="org.apache.hadoop.io.NullWritable",
valueClass="org.elasticsearch.hadoop.mr.LinkedMapWritable",
conf=es_write_conf)
Program trace:
link to the image
This is a setting of the mapping to the index, u can find out in the official user guide.
The sample code like this:
curl -XPOST localhost:9200/test -d '{
"settings" : {
"number_of_shards" : 1,
"number_of_replicas":0
},
"mappings" : {
"test1" : {
"_id":{"path":"mainkey"},
"_source" : { "enabled" : false },
"properties" : {
"mainkey" : { "type" : "string", "index" : "not_analyzed" }
}
}
}
}'

Updating a Set in Dynamo db using Node Js

I am trying to do one of the most simple operations "Update" in a dynamo db list.
Table Schema -
businessId : String, customers: StringSet, itemCode : NumberSet
I have an entry inserted via put -
bussinessId = "sampleBusiness", cuatomers 0: "cust1", itemCode 0: 4554
I want to add more items using update and here is what I have tried -
var updateRequest = {
'TableName' : tableName,
'Key' : {
'businessId' : {
"S" : businessId
}
},
'UpdateExpression' : "SET itemCode[2] =:attrValue",
'ExpressionAttributeValues' : {
':attrValue' : {
"N" : "564564"
}
}
};
This gives me error -
Document Path provided in document is invalid
I wanted to append new entries so tried this as well -
var sm = [];
sm[0] = "56465";
//Add business to
var updateRequest = {
'TableName' : tableName,
'Key' : {
'businessId' : {
"S" : businessId
}
},
'UpdateExpression' : 'SET #attrName = list_append(#attrName, :attrValue)',
'ExpressionAttributeNames' : {
'#attrName' : 'itemCode'
},
'ExpressionAttributeValues' : {
':attrValue' : {
"NS" : sm
}
}
};
This gives:
ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function; operator or function: list_append, operand type: NS
Also attempted this -
':attrValue' : {
"N" : "4564"
}
But same error.
As per the example provided in http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html , it adds a new element to the FiveStar review list. The expression attribute name #pr is ProductReviews; the attribute value :r is a one-element list. If the list previously had two elements, [0] and [1], then the new element will be [2].
SET #pr.FiveStar = list_append(#pr.FiveStar, :r)
which Says :r is one element list
I am missing some thing here. Request if any one can help. Struck on this for long time. I just want to append elements in set in dynamo db using nodeJS.
It looks like this:
'ExpressionAttributeValues' : {
':attrValue' : {
"NS" : sm
}
}
Should be this:
'ExpressionAttributeValues' : {
':attrValue' : {
"S" : sm
}
}
Or you need to cast this value sm[0] = "56465"; to a Number Number("56465") and change the :attrValue data type "S" to "N". Depends on how you have your table configured.
It's possible too that you should assign :attrValue to be "S" : sm[0] because right now you are passing an "S" a whole array.
I got a proper solution
var item = {"endTime": "7pm", "imageName": "7abcd", "startTime": "7pm"};
dynamo.updateItem({
TableName:'TableName',
Key:{"BucketName":"abcdefg" },
UpdateExpression : "SET #attrName = list_append(#attrName, :attrValue)",
ExpressionAttributeNames : {
"#attrName" : "ImageLists"
},
ExpressionAttributeValues : {
':attrValue' : [item]
}
},function(err, data) {
if (err)
console.log(err);
else
console.log(data)
});

Resources