Terraform function lookup within lookup - amazon-s3

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"]

Related

SQLSTATE[22007]: Invalid datetime forma

I try to save some data that it brings me from my view, which is a table, but I don't know why it throws me that error with the insert.
result of insert
this is my view:
table of view
this is my controller:
$checked_array = $_POST['id_version'];
foreach ($request['id_version'] as $key => $value) {
if (in_array($request['id_version'][$key], $checked_array))
{
$soft_instal = new Software_instalacion;
$soft_instal->id_instalacion = $instalaciones->id;
$soft_instal->id_historial = $historial->id;
$soft_instal->id_usuario = $request->id_usuario;
$soft_instal->id_version = $_POST['id_version'][$key];
$soft_instal->obs_software = $_POST['obs_software'][$key];
$soft_instal->id_tipo_venta = $_POST['id_tipo_venta'][$key];
$soft_instal->save();
}
}
id_tipo_venta seems to be an empty string which is apparently not valid.
You can try debugging what you get in :
var_dump($_POST['id_tipo_venta'][$key]);
die;
Your database field expects to receive an integer. Therefore, using the intval() function can solve your problem.
Indeed, I think your code returns an alphanumeric string.
Therefore, the code below will return 0 in all cases if no version is returned (not set, string or simply null):
$soft_instal->id_tipo_venta = intval($_POST['id_tipo_venta'][$key]);
On the other hand, intval() will always convert to int, so a decimal will be converted, example :
intval("1.1") // returns 1
intval("v1.1") // returns 0
If this is not the desired behavior, maybe you should think about changing your database type.
EDIT :
Of course, you can also set the value as null if you prefer to 0. You must allow nullable values in your database.
id_tipo_venta can not be empty, try with some number or change type column to varchar in the database

Terraform conditions in a module

I am trying to create some simple logic when calling applicationg gateway module.
When creating WAF v2 application gateway I want to specify more attributes that simple application gateway can't handle and they won't be described.
resource "azurerm_application_gateway" {
name = var.appgatewayname
resource_group_name = data.azurerm_resource_group.rg.name
location = data.azurerm_resource_group.rg.location
......................
waf_configuration {
enabled = "${length(var.waf_configuration) > 0 ? lookup(var.waf_configuration, "enabled", "") : null }"
firewall_mode = "${length(var.waf_configuration) > 0 ? lookup(var.waf_configuration, "firewall_mode", "") : null }"
............
Calling module:
module "GWdemo" {
source = "./...."
sku-name = "WAF_v2"
sku-tier = "WAF_v2"
sku-capacity = 1
waf-configuration = [
{
enabled = true
firewall_mode = "Detection"
}
Am I thinking right that if waf-configuration map is specified it should specify following settings is applied and if not than null?
When working with Terraform we often want to reframe problems involving a conditional test into problems involving a collection that may or may not contain elements, because the Terraform language features are oriented around transforming collections into configuration on an element-by-element basis.
In your case, you have a variable that is already a list, so it could work to just ensure that its default value is an empty list rather than null, and thus that you can just generate one waf_configuration block per element:
variable "waf_configuration" {
type = list(object({
enabled = bool
firewall_mode = string
}))
default = []
}
Then you can use a dynamic block to generate one waf_configuration block per element of that list:
dynamic "waf_configuration" {
for_each = var.waf_configuration
content {
enabled = waf_configuration.value.enabled
firewall_mode = waf_configuration.value.firewall_mode
}
}
Although it doesn't seem to apply to this particular example, another common pattern is a variable that can be set to enable something or left unset to disable it. For example, if your module was designed to take only a single optional WAF configuration, you might define the variable like this:
variable "waf_configuration" {
type = object({
enabled = bool
firewall_mode = string
})
default = null
}
As noted above, the best way to work with something like that in Terraform is to recast it as a list that might be empty. Because it's a common situation, there is a shorthand for it via splat expressions:
dynamic "waf_configuration" {
for_each = var.waf_configuration[*]
content {
enabled = waf_configuration.value.enabled
firewall_mode = waf_configuration.value.firewall_mode
}
}
When we apply the [*] operator to a value of a non-list/non-set type, Terraform will test to see if the value is null. If it is null then the result will be an empty list, while if it is not null then the result will be a single-element list containing that one value.
After converting to a list we can then use it in the for_each argument to dynamic in the usual way, accessing the attributes from that possible single element inside the content block. We don't need to repeat the conditionals for each argument because the content block contents are evaluated only when the list is non-empty.
I would encourage you to upgrade to Terraform v0.12.x and this should get a much easier to do. I would leverage the new dynamic block syntax to make the block optional based on whatever condition you need to use.
Here is a rough example, but should get you going in the correct direction.
dynamic "waf-configuration " {
for_each = length(var.waf_configuration) > 0 ? [] : [1]
content {
enabled = "${length(var.waf_configuration) > 0 ? lookup(var.waf_configuration, "enabled", "") : null }"
firewall_mode = "${length(var.waf_configuration) > 0 ? lookup(var.waf_configuration, "firewall_mode", "") : null }"
}
}

Update terraform variable from resource

I want to update a variable from a resource on terraform.
Is that possible? I'm a bit new in this technology.
variable "contador" {
default = 0
}
resource "azurerm_managed_disk" "test-disks-test3" {
count = "${length(var.disks_size) * var.vm_number}"
name = "SRV${var.service_base_name}${var.service_environment}01-DATADISK-0${count.index}"
location = "westeurope"
resource_group_name = "${azurerm_resource_group.test-rg-test3.name}"
storage_account_type = "${var.disk_tier}_${var.disk_replication}"
create_option = "Empty"
disk_size_gb = "${element(var.disks_size, count.index)}"
var.contador = "${count.index % length(var.disks_size) == (length(var.disks_size) - 1) ? (var.contador + 1) : var.contador}"
tags{
environment = "TestWork"
}
}
The line in question is:
var.contador = "${count.index % length(var.disks_size) == (length(var.disks_size) - 1) ? (var.contador + 1) : var.contador}"
TL;DR
You can't update the variable.
About HCL
Terraform is using the HCL language.
This language is declarative and not procedural or OOP.
It means once it is defined, terraform doesn't not allow you to modify its value at the run time.
From the terraform documentation:
The default value of an input variable must be a literal value, containing no interpolation expressions. To assign a name to an expression so that it may be re-used within a module, use Local Values instead.
Moreover in your resource block, you can only use arguments defined by that resource and var.contador is not one of them.

Terraform combine 2 variables into a new variable

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.

Sales Order Confirmation Report - SalesConfirmDP

I am modifying the SalesConfirmDP class and trying to add the CustVendExternalItem.ExternalItemTxt field into a new field I have created.
I have tried a couple of things but I do not think my syntax was correct i.e I declare the CustVendExternalItem table in the class declaration. But then when I try to insert CustVendExternalItem.ExternalItemTxt into my new field, it does not populate, I guess there must be a method which I need to include?
If anyone has any suggestion it would be highly appreciated.
Thank you in advance.
private void setSalesConfirmDetailsTmp(NoYes _confirmTransOrTaxTrans)
{
DocuRefSearch docuRefSearch;
// Body
salesConfirmTmp.JournalRecId = custConfirmJour.RecId;
if(_confirmTransOrTaxTrans == NoYes::Yes)
{
if (printLineHeader)
{
salesConfirmTmp.LineHeader = custConfirmTrans.LineHeader;
}
else
{
salesConfirmTmp.LineHeader = '';
}
salesConfirmTmp.ItemId = this.itemId();
salesConfirmTmp.Name = custConfirmTrans.Name;
salesConfirmTmp.Qty = custConfirmTrans.Qty;
salesConfirmTmp.SalesUnitTxt = custConfirmTrans.salesUnitTxt();
salesConfirmTmp.SalesPrice = custConfirmTrans.SalesPrice;
salesConfirmTmp.DlvDate = custConfirmTrans.DlvDate;
salesConfirmTmp.DiscPercent = custConfirmTrans.DiscPercent;
salesConfirmTmp.DiscAmount = custConfirmTrans.DiscAmount;
salesConfirmTmp.LineAmount = custConfirmTrans.LineAmount;
salesConfirmTmp.CurrencyCode = custConfirmJour.CurrencyCode;
salesConfirmTmp.PrintCode = custConfirmTrans.TaxWriteCode;
if (pdsCWEnabled)
{
salesConfirmTmp.PdsCWUnitId = custConfirmTrans.pdsCWUnitId();
salesConfirmTmp.PdsCWQty = custConfirmTrans.PdsCWQty;
}
**salesConfirmTmp.ExternalItemText = CustVendExternalItem.ExternalItemTxt;**
if ((custFormletterDocument.DocuOnConfirm == DocuOnFormular::Line)
|| (custFormletterDocument.DocuOnConfirm == DocuOnFormular::All))
{
docuRefSearch = DocuRefSearch::newTypeIdAndRestriction(custConfirmTrans,
custFormletterDocument.DocuTypeConfirm,
DocuRestriction::External);
salesConfirmTmp.Notes = Docu::concatDocuRefNotes(docuRefSearch);
}
salesConfirmTmp.InventDimPrint = this.printDimHistory();
Well, AX cannot guess which record you need, there is a helper class CustVendExternalItemDescription to deal with it:
boolean found;
str externalItemId;
...
[found, externalItemId, salesConfirmTmp.ExternalItemText] = CustVendExternalItemDescription::findExternalItemDescription(
ModuleCustVend::Cust,
custConfirmTrans.ItemId,
custConfirmTrans.inventDim(),
custConfirmJour.OrderAccount,
CustTable::find(custConfirmJour.OrderAccount).CustItemGroupId);
The findExternalItemDescription method returns more information than you need here, but you have to define variables to store it anyway.
Well, the steps to solve this problem are fairly easy and i will try to give you a step by step approach how to solve this problem.
1) Are you initialising CustVendExternalItem properly? Make a record of the same and initialise it as Jan has shown above, then debug your code and see if the value is being initialised in your DP class.
2)If your value is being initialised correctly, but it is not showing up in the report design there can be multiple issues such as:
Overlapping of text boxes.
Insufficient space for the given field
Some report parameter/property not being set correctly which causes
your value not to show up on the report.
Check these one by one and you should end up arriving towards a solution