Expected Behaviour
I would like to make a boolean variable 'var.enable_retention_policy' true based on the output of mapped value 'var.ds_allmetrics_retention_days'
Actual Behaviour
throws error (see Error output)
Error Output
Error: Inconsistent conditional result types
on ..\db\main.tf line 37, in module "diagnostic_mssql_db":
37: "WorkloadManagement" = var.workload_management > 0 ? var.workload_management : var.enable_retention_policy
The true and false result expressions must have consistent types. The given
expressions are number and bool, respectively.
Terraform (and AzureRM Provider) Version
Affected Resource(s)
azurerm_v2.41.0
terraform v0.13.0
Terraform Configuration Files
Main.tf
data "azurerm_storage_account" "storage_account" {
name = var.storage_account
resource_group_name = var.sa_resource_group
}
resource "azurerm_monitor_diagnostic_setting" "diagsetting" {
name = var.target_resource_name
target_resource_id = var.target_resource_id
storage_account_id = data.azurerm_storage_account.storage_account.id
dynamic "log" {
for_each = keys(var.ds_log_api_endpoints)
content {
category = log.value
enabled = true
retention_policy {
enabled = var.enable_retention_policy
days = lookup(var.ds_log_api_endpoints, log.value, 0)
}
}
}
dynamic "metric" {
for_each = keys(var.ds_allmetrics_retention_days)
content {
category = metric.value
retention_policy {
enabled = var.enable_retention_policy
days = lookup(var.ds_allmetrics_retention_days, metric.value, 0)
}
}
}
}
Variables.tf
# boolean variable
variable "enable_retention_policy" {
type = bool
description = "toggle on/off the retention policy for the metric"
default = false
}
# mapped values
variable "ds_allmetrics_retention_days" {
type = map
description = "Azure monitor diagnostic setting category for retention in days of target resource."
default = {}
}
Module call
module "diagnostic_mssql_db" {
source = "github.com/faraday23/terraform-azurerm-monitor-diagnostic-setting.git"
storage_account = var.storage_account
sa_resource_group = var.sa_resource_group
target_resource_id = azurerm_mssql_database.db.id
target_resource_name = azurerm_mssql_database.db.name
enable_retention_policy = var.enable_retention_policy
ds_log_api_endpoints = { "AutomaticTuning" = var.automatic_tuning > 0 ? var.automatic_tuning : var.enable_retention_policy,
"Blocks" = var.blocks > 0 ? var.blocks : var.enable_retention_policy,
"DatabaseWaitStatistics" = var.database_wait_statistics > 0 ? var.database_wait_statistics : var.enable_retention_policy,
"Deadlocks" = var.deadlocks > 0 ? var.deadlocks : var.enable_retention_policy,
"Errors" = var.error_log > 0 ? var.error_log : var.enable_retention_policy,
"Timeouts" = var.timeouts > 0 ? var.timeouts : var.enable_retention_policy,
"QueryStoreRuntimeStatistics" = var.query_store_runtime_statistics > 0 ? var.query_store_runtime_statistics : var.enable_retention_policy,
"QueryStoreWaitStatistics" = var.query_store_wait_statistics > 0 ? var.query_store_wait_statistics : var.enable_retention_policy,
"SQLInsights" = var.sql_insights > 0 ? var.sql_insights : var.enable_retention_policy
}
ds_allmetrics_retention_days = { "Basic" = var.basic > 0 ? var.basic : var.enable_retention_policy,
"InstanceAndAppAdvanced" = var.instance_and_app_advanced > 0 ? var.instance_and_app_advanced : var.enable_retention_policy,
"WorkloadManagement" = var.workload_management > 0 ? var.workload_management : var.enable_retention_policy
}
}
The error message indicates that the issue is with WorkloadManagement. In your case you have mixture of bool and int which is incorrect. Conditional Expressions must be of same type:
The two result values may be of any type, but they must both be of the same type so that Terraform can determine what type the whole conditional expression will return without knowing the condition value.
Thus, you can use tonumber to change bool to int:
Update based on Martin comment
The original answer used tonumber(var.enable_retention_policy) which was incorrect, as you can't convert bool to number. To correct answer is then:
"WorkloadManagement" = (var.workload_management > 0
? var.workload_management
: (var.enable_retention_policy ? 1 : 0))
Related
Is it possible to hide a facet based on the current table ?
Exemple, I have a "news" table and a table "project".
But if I do this :
facets.state {
label.data = LLL:EXT:skin/Resources/Private/Language/locallang.xlf:search.rfp_state
field = state_intS
renderingInstruction = TEXT
renderingInstruction {
field = optionValue
wrap = {LLL:EXT:projects/Resources/Private/Language/locallang_db.xlf:tx_projects_domain_model_requestforprojects.state.items.|}
insertData = 1
}
includeInAvailableFacets = 0
}
The includeInAvailableFacets is
for both my news and project
Looked into the docs, but couldn't find what i've been looking for...
https://docs.typo3.org/p/apache-solr-for-typo3/solr/master/en-us/Configuration/Reference/TxSolrSearch.html#faceting-facets-facetname-includeinavailablefacets
Got it !
You have to declare condition to your precise page like this :
Where 1772 is your page id. Found a lead here : https://docs.typo3.org/m/typo3/reference-typoscript/8.7/en-us/Conditions/Reference/
[globalVar = TSFE:id =1772] && [globalVar = TSFE:id = {$plugin.tx_anrskin.settings.pages.solrSortDateDesc}] && [globalVar = GP:q =]
plugin.tx_solr.search.query.sortBy = sortDate_dateS desc
plugin.tx_solr.search.sorting = 0
plugin.tx_solr.search.query.returnFields = *, score
plugin.tx_solr.search.faceting.facets.dateinterval.includeInAvailableFacets = 0
plugin.tx_solr.search.faceting.facets.item.includeInAvailableFacets = 0
plugin.tx_solr.search.faceting.facets.name.includeInAvailableFacets = 0
[globalVar]
I am trying to create a database using terraform and this seems very complicated for a poor query...
Could you help me, please?
I have tried null_resource with local-exec and data "external" Python...
I think I am looking the wrong way
ex which doesn't works in terraform 0.12
resource "null_resource" "create-endpoint" {
provisioner "local-exec" {
query = <<EOF
{
CREATE EXTERNAL TABLE `dashboard_loading_time`(
`timestamp_iso` string,
`app_identification` struct<service:string,app_name:string,app_type:string,stage:string>,
`user` struct<api_gateway_key:struct<id:string,name:string>,mashery_key:struct<id:string,name:string>,employee:struct<id:string,name:string>>,
`action` struct<action_type:string,path:string>,
`result` struct<status:string,http_status:string,response:struct<response:string>>)
PARTITIONED BY (
`year` int)
ROW FORMAT SERDE
'org.openx.data.jsonserde.JsonSerDe'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
's3://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/dev'
}
EOF
command = "aws athena start-query-execution --query-string "query""
}
}
I would like to find the simplest way to do this using terraform.
If you wanna make it for athena, need to make glue resources.
try below code with terraform.
variable "service_name" {
default = "demo-service"
}
variable "workspace" {
default = "dev"
}
variable "columns" {
default = {
id = "int"
type = "string"
status = "int"
created_at = "timestamp"
}
}
resource "aws_glue_catalog_database" "athena" {
name = "${var.service_name}_db"
}
resource "aws_glue_catalog_table" "athena" {
name = "${var.service_name}_logs"
database_name = "${aws_glue_catalog_database.athena.name}"
table_type = "EXTERNAL_TABLE"
parameters = {
EXTERNAL = "TRUE"
}
storage_descriptor {
location = "s3://${var.service_name}-${var.workspace}-data-pipeline/log/"
input_format = "org.apache.hadoop.mapred.TextInputFormat"
output_format = "org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat"
ser_de_info {
name = "jsonserde"
serialization_library = "org.openx.data.jsonserde.JsonSerDe"
parameters = {
"serialization.format" = "1"
}
}
dynamic "columns" {
for_each = "${var.columns}"
content {
name = "${columns.key}"
type = "${columns.value}"
}
}
}
partition_keys {
name = "year"
type = "string"
}
partition_keys {
name = "month"
type = "string"
}
partition_keys {
name = "day"
type = "string"
}
partition_keys {
name = "hour"
type = "string"
}
}
refer to this repository : aws-serverless-data-pipeline-by-terraform
resource "aws_glue_catalog_table" "aws_glue_catalog_table" {
name = "mytable"
database_name = aws_glue_catalog_database.aws_glue_catalog_database.name
table_type = "EXTERNAL_TABLE"
parameters = {
"classification" = "json"
}
storage_descriptor {
location = "s3://mybucket/myprefix"
input_format = "org.apache.hadoop.mapred.TextInputFormat"
output_format = "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat"
ser_de_info {
name = "myserdeinfo"
serialization_library = "org.openx.data.jsonserde.JsonSerDe"
parameters = {
"paths" = "jsonrootname"
}
}
columns {
name = "column1"
type = "array<struct<resourcearn:string,tags:array<struct<key:string,value:string>>>>"
}
}
partition_keys {
name = "part1"
type = "string"
}
partition_keys {
name = "part2"
type = "string"
}
}
I created sql with enable/disable options with var.sql_server_enable, but I have a problem about output. If the var.sql_server_enable is 0, the azurerm_sql_server.sql_server.name is going to be null and I get the following error.
resource "azurerm_sql_server" "sql_server" {
count = "${var.sql_server_enable ? 1 : 0}"
name = "${var.sql_server_name}"
resource_group_name = "${var.sql_server_resource_group_name}"
location = "${var.sql_server_location}"
version = "${var.sql_server_version}"
administrator_login = "${var.sql_server_admin_user}"
administrator_login_password = "${var.sql_server_admin_pass}"
}
output "sql_server_name_output" {
value = "${var.sql_server_enable == "1" ? azurerm_sql_server.sql_server.name : var.null }"
}
Error: Error running plan: 1 error occurred:
* module.hello.module.azure_sql_server_hello_staging.output.sql_server_name_output: Resource 'azurerm_sql_server.sql_server' not found for variable 'azurerm_sql_server.sql_server.name'
You could output
value = "${var.sql_server_enable ? azurerm_sql_server.sql_server[0].name : var.null }". When you terraform apply, you could type "1" for true, "0" for false when you input values for variable "sql_server_enable".
This works for me with Terraform v0.12.6 + provider.azurerm v1.32.1, you can upgrade it if you need.
variable "sql_server_enable" {
type = bool
}
variable "null" {
default = "this is empty"
}
resource "azurerm_sql_server" "sql_server" {
count = "${var.sql_server_enable ? 1 : 0}"
name = "mysqlserver123qaz"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
version = "12.0"
administrator_login = "mradministrator"
administrator_login_password = "thisIsDog11"
}
output "sql_server_name_output" {
value = "${var.sql_server_enable ? azurerm_sql_server.sql_server[0].name : var.null }"
}
Result1
Result2
Hope this could help you.
Thanks for the answer, but sql_server_name_output variable is used on the other module. It needs string value. Then i use var.null rather than null. After i follow your suggestion, I get another error below. Do you have any other suggestion?
Error: Inconsistent conditional result types
on ../modules/azure_sql_server/output.tf line 9, in output "sql_server_name_output":
9: value = "${var.sql_server_enable ? azurerm_sql_server.sql_server[*].name : var.null }"
|----------------
| azurerm_sql_server.sql_server is tuple with 1 element
| var.null is "null"
| var.sql_server_enable is true
The other resource that needs azurerm_sql_server.sql_server is below.
resource "azurerm_sql_firewall_rule" "sql_firewall_rule" {
count = "${var.sql_fw_enable == "1" ? 1 : 0}"
name = "${var.sql_fw_rule_name}"
resource_group_name = "${var.sql_fw_rule_resource_group_name}"
server_name = "${azurerm_sql_server.sql_server}"
start_ip_address = "${var.sql_fw_rule_start_ip}"
end_ip_address = "${var.sql_fw_rule_end_ip}"
}
I am using model.GetType().GetProperties() with foreach to compare properties of 2 object of same class.
like this
foreach (var item in kayit.GetType().GetProperties())
{
var g = item.GetValue(plu);
var b = item.GetValue(kayit);
if (g is string && b is string&& g!=b)
{
a += item.Name + "*";
}
else if (g is DateTime&& b is DateTime&& g!=b)
{
a += item.Name + "*";
}
}
But the problem is even if they have the same value g!=b returns a true all the time. I have used a break point to prove this and they are literally same thing. Actually I am taking the value putting it in textbox then creating another class after button click and comaring to see the changed properties. So even if I don't change anything it doesn't read the mas equals. Can someone help me about this please?
more info:
I get the plu from database and populate my control with it:
txtorder.Text = plu.OrderNo;
dtporder.Value = nulldate(plu.OrderDate);
dtp1fit.Value = nulldate(plu.FirstFitDate);
dtp1yorum.Value = nulldate(plu.FirstCritDate);
dtp2fit.Value = nulldate(plu.SecondFitDate);
dtp2yorum.Value = nulldate(plu.SecondCritDate);
dtpsizeset.Value = nulldate(plu.SizeSetDate);
dtpsizesetok.Value = nulldate(plu.SizeSetOkDate);
dtpkumasplan.Value = nulldate(plu.FabricOrderByPlan);
txtTedarikci.Text = plu.Fabric_Supplier;
dtpkumasFP.Value = nulldate(plu.FabricOrderByFD);
dtpfabarrive.Value = nulldate(plu.FabricArrive);
dtpbulk.Value = nulldate(plu.BulkFabricDate);
dtpbulkok.Value = nulldate(plu.BulkConfirmDate);
dtpaccessory.Value = nulldate(plu.AccessoriesDate);
dtpaccessoryarrive.Value = nulldate(plu.AccessoriesArriveDate);
dtpcutok.Value = nulldate(plu.ProductionStartConfirmation);
dtpcutstart.Value = nulldate(plu.ProductionStart);
dtpshipmentdate.Value = nulldate(plu.ShipmentDate);
dtpshipmentsample.Value = nulldate(plu.ShipmentSampleDate);
dtpshippedon.Value = nulldate(plu.Shippedon);
nulldate is just a method where I change null values to my default value.
And this is what I do after button click:
var kayit = new uretim();
kayit.OrderNo = txtorder.Text.ToUpper();
kayit.OrderDate = vdat(dtporder.Value);
kayit.FirstFitDate = vdat(dtp1fit.Value);
kayit.FirstCritDate = vdat(dtp1yorum.Value);
kayit.SecondFitDate = vdat(dtp2fit.Value);
kayit.SecondCritDate = vdat(dtp2yorum.Value);
kayit.SizeSetDate = vdat(dtpsizeset.Value);
kayit.SizeSetOkDate = vdat(dtpsizesetok.Value);
kayit.FabricOrderByPlan = vdat(dtpkumasplan.Value);
kayit.Fabric_Supplier = txtTedarikci.Text;
kayit.FabricOrderByFD = vdat(dtpkumasFP.Value);
kayit.FabricArrive = vdat(dtpfabarrive.Value);
kayit.BulkFabricDate = vdat(dtpbulk.Value);
kayit.BulkConfirmDate = vdat(dtpbulkok.Value);
kayit.AccessoriesDate = vdat(dtpaccessory.Value);
kayit.AccessoriesArriveDate = vdat(dtpaccessoryarrive.Value);
kayit.ProductionStartConfirmation = vdat(dtpcutok.Value);
kayit.ProductionStart = vdat(dtpcutstart.Value);
kayit.ShipmentDate = vdat(dtpshipmentdate.Value);
kayit.ShipmentSampleDate = vdat(dtpshipmentsample.Value);
kayit.Shippedon = vdat(dtpshippedon.Value);
kayit.Status = true;
kayit.WrittenDate = DateTime.Now;
kayit.GuidKey = plu.GuidKey != null ? plu.GuidKey : Guid.NewGuid().ToString("N");
I have proven by breakpoint that values are actually same. But the != check retruns a true.
When you are doing
g != b
compiler doesn't know that these objects are strings to compare so it compares their references. You can do:
g.Equals(b) //be carefull if one of them is null
or
g.ToString() != b.ToString()
EDIT
You can compare them after you check the type:
if (g is string && b is string)
{
if( g.ToString() != b.ToString() ){
}
}
lets say we have a custom class named orderFile and this class contains three properties.
class orderFile {
var name = String()
var id = Int()
var status = String()
}
a lot of them stored into an array
var aOrders : Array = []
var aOrder = orderFile()
aOrder.name = "Order 1"
aOrder.id = 101
aOrder.status = "closed"
aOrders.append(aOrder)
var aOrder = orderFile()
aOrder.name = "Order 2"
aOrder.id = 101
aOrder.status = "open"
aOrders.append(aOrder)
var aOrder = orderFile()
aOrder.name = "Order 2"
aOrder.id = 101
aOrder.status = "cancelled"
aOrders.append(aOrder)
var aOrder = orderFile()
aOrder.name = "Order 2"
aOrder.id = 101
aOrder.status = "confirmed"
aOrders.append(aOrder)
Question is: How will I sort them based on status according to open, confirm, close and cancelled?
You have to provide a value that will yield the appropriate ordering when compared in the sort function.
For example:
extension orderFile
{
var statusSortOrder: Int
{ return ["open","confirmed","closed","cancelled"].index(of: status) ?? 0 }
}
let sortedOrders = aOrders.sorted{$0.statusSortOrder < $1. statusSortOrder}
In your code you should make an array to store each aOrder with aOrders.append(aOrder) at each aOrder defination.
Then sort it with below code, refor this for more.
aOrders.sorted({ $0.status > $1.status })
The answer for swift 3 is as following
Ascending:
aOrders = aOrders.sorted(by:
{(first: orderFile, second: orderFile) -> Bool in
first.status > second.status
}
)
Descending:
aOrders = aOrders.sorted(by:
{(first: orderFile, second: orderFile) -> Bool in
first.status < second.status
}
)