Unable to update firewall rules for mysqlserver from app service - mysql

I am trying to update vnet rules for mysqlserver from app service.
App Service and mysqlserver tf code is like below:
module "app_service" {
for_each = coalesce(var.app_service, {})
source = "company/org/app-service/azurerm"
version = "1.1"
location = var.environment_hosting_region
resource_group_name = var.environment_resource_groups
tags = try(each.value.tags, local.tags)
name = try(each.value.name, null)
}
variable "mysqlserver" {
description = "Map of mysqlserver objects"
type = any
default = null
}
module "mysqlserver" {
for_each = coalesce(var.mysqlserver, {})
source = "company/org/mysqlserver/azurerm"
version = "1.1"
administrator_login = try(each.value.administrator_login, null)
administrator_login_password = try(each.value.administrator_login_password, null)
backup_retention_days = try(each.value.backup_retention_days, null)
charset = try(each.value.charset, "utf8")
collation = try(each.value.collation, "utf8_unicode_ci")
create_mode = try(each.value.create_mode, "Default")
creation_source_server_id = try(each.value.creation_source_server_id, null)
database_names = try(each.value.database_names, [])
default_rules = try(each.value.default_rules, true)
enable_account_admins = try(each.value.enable_account_admins, true)
enable_threat_detection_policy = try(each.value.enable_threat_detection_policy, true)
geo_redundant_backup = try(each.value.geo_redundant_backup, false)
identity_type = try(each.value.identity_type, null)
location = var..environment_hosting_region
mysql_version = try(each.value.mysql_version, null)
name = try(each.value.name, null)
resource_group_name = var..environment_resource_groups
restore_point_in_time = try(each.value.restore_point_in_time, null)
sku_name = try(each.value.sku_name, null)
storage_mb = try(each.value.storage_mb, null)
tags = try(each.value.tags, local.tags)
threat_log_retention_days = try(each.value.threat_log_retention_days, 7)
vnet_rules = [for subnet in try(each.value.subnet_ref, []) : data.azurerm_subnet.subnet[subnet].id]
nsg_rules = try(each.value.nsg_rules, [])
firewall_rules = each.value.app_service_ref != null ? module.app_service[each.value.app_service_ref].firewall_rules : null
}
I get multiple errors as like below:
│ Error: waiting for create/update of Firewall Rule: (Name "rule_x.y.z.170" / Server Name "u2zuuhjjsddm002" / Resource Group "mysqlserver-rg"): Code="InvalidParameterValue" Message="Invalid value given for parameter
'{0}'. Specify a valid parameter value."
│
│ with module.mysqlserver["patterns_default_mysqlserver"].azurerm_mysql_firewall_rule.firewall_rules[53],
│ on .terraform/modules/mysqlserver/main.tf line 69, in resource "azurerm_mysql_firewall_rule" "firewall_rules":
│ 69: resource "azurerm_mysql_firewall_rule" "firewall_rules" {
Mysqlserver module code as per below:
main.tf
locals {
firewall_rules = concat(local.tfe_firewall.tfe_servers, local.default_fw_rules, var.firewall_rules)
}
resource "azurerm_mysql_server" "mysql" {
name = var.name
resource_group_name = var.resource_group_name
ssl_enforcement_enabled = true
ssl_minimal_tls_version_enforced = "TLS1_2"
dynamic "identity" {
for_each = var.identity_type != null ? [""] : []
content {
type = var.identity_type
}
}
threat_detection_policy {
enabled = var.enable_threat_detection_policy
email_account_admins = var.enable_account_admins
retention_days = var.threat_log_retention_days
}
tags = var.tags
}
resource "azurerm_mysql_database" "databases" {
count = length(var.database_names)
name = element(var.database_names, count.index)
resource_group_name = var.resource_group_name
server_name = azurerm_mysql_server.mysql.name
charset = var.charset
collation = var.collation
}
resource "azurerm_mysql_virtual_network_rule" "subnets" {
count = length(var.vnet_rules)
name = "subnet-${count.index}"
resource_group_name = var.resource_group_name
server_name = azurerm_mysql_server.mysql.name
subnet_id = element(var.vnet_rules, count.index)
}
resource "azurerm_network_security_rule" "mysql-nsg" {
count = length(var.nsg_rules)
name = "NSG-MYSQL-${count.index}"
priority = 200+count.index
direction = "Outbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3306"
source_address_prefix = var.nsg_rules[count.index]["source_address_prefix"]
destination_address_prefix = "Sql"
resource_group_name = var.resource_group_name
network_security_group_name = var.nsg_rules[count.index]["network_security_group_name"]
}
resource "azurerm_mysql_firewall_rule" "firewall_rules" {
count = local.firewall_rules == [] ? 0 : length(local.firewall_rules)
name = local.firewall_rules[count.index]["name"]
resource_group_name = var.resource_group_name
server_name = azurerm_mysql_server.mysql.name
start_ip_address = local.firewall_rules[count.index]["start_ip_address"]
end_ip_address = local.firewall_rules[count.index]["end_ip_address"]
depends_on = [
azurerm_mysql_server.mysql
]
}
variables.tf
variable "firewall_rules" {
description = "List of firewall rules to be attached to the MySQL server."
type = list(object({
name = string
start_ip_address = string
end_ip_address = string
}))
default = []
}
variable "nsg_rules" {
description = "NSG Rules"
type = list(object({
source_address_prefix = string
network_security_group_name = string
}))
default = []
}
variable "vnet_rules" {
description = "List of subnets to add to vnet_rules"
type = list(string)
default = []
}
variable "charset" {
description = "Specifies the Charset for the MySQL Database, which needs to be a valid MySQL Charset. Available option are (https://dev.mysql.com/doc/refman/5.7/en/charset-charsets.html)."
type = string
default = "utf8"
}
variable "collation" {
description = "Specifies the Collation for the MySQL Database, which needs to be a valid MySQL Collation. Available option are (https://dev.mysql.com/doc/refman/5.7/en/charset-mysql.html)."
type = string
default = "utf8_unicode_ci"
}
variable "default_rules" {
description = "Variable to control whether to turn on default rules"
type = bool
default = true
}
Unable to understand what is the issue and how can it be resolved.
Any guidance shall be much appreciated.

Related

Terraforms to create Azure API Management Private Endpoint

I'm trying to script creation of an Azure API Management having a Private Endpoint within a VNET Subnet.
I'm able to create it manually no problem in Azure Portal, but can't quite figure out the terraform script.
The VNET and Subnet are created in a separate process, so they are not in the Terraform script but for the API Management piece I have:
resource "azurerm_api_management" "app" {
location = var.the_location
resource_group_name = "${var.the_resource_group}"
name = "${var.the_prefix}-api-mgmt"
publisher_email = var.api_mgmt_publisher_email
publisher_name = var.api_mgmt_publisher_name
sku_name = "${var.api_mgmt_sku}_1"
tags = var.resource_tags }
resource "azurerm_private_endpoint" "endpoint" {
name = "${var.the_prefix}-api-privateendpoint"
location = var.the_location
resource_group_name = var.the_resource_group
subnet_id = var.subnetId
tags = var.resource_tags
private_service_connection {
name = "api-privateserviceconnection"
private_connection_resource_id = azurerm_api_management.app.id
is_manual_connection = false
subresource_names = [] }}
The var.subnetId is the full id of the subnet ie.
/subscriptions/{subscriptionId}/resourceGroups/OpenEHR/providers/Microsoft.Network/virtualNetworks/OpenEHR-VNET/subnets/API-Subnet
The error I get is
Error: creating Private Endpoint "i365sabppdsdevtb-api-privateendpoint" (Resource Group "i365-uks-ehsabppds-devtb-rg"): network.PrivateEndpointsClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="MissingParameterOnPrivateLinkServiceConnection" Message="Private link service connection /subscriptions/8cb2b2d3-9411-46e4-926d-22d6378349bc/resourceGroups/i365-uks-ehsabppds-devtb-rg/providers/Microsoft.Network/privateEndpoints/i365sabppdsdevtb-api-privateendpoint/privateLinkServiceConnections/api-privateserviceconnection is missing required parameter 'group Id'." Details=[]
I think the error is something to so with subresource_names but I can't work out what to put in there.
I tried [ "sites" ] but then I get the error:
│ Error: creating Private Endpoint "i365sabppdsdevtb-api-privateendpoint" (Resource Group "i365-uks-ehsabppds-devtb-rg"): network.PrivateEndpointsClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="PrivateEndpointBadRequest" Message="Call to Microsoft.ApiManagement/service failed. Error message: The Request has invalid groupId sites." Details=[]
Any ideas, much appreciated.
Thanks.
Issue was caused because of the private service connection resource id and sub resource names. Please use below configuration
private_connection_resource_id = azurerm_api_management.app.id
subresource_names = ["Gateway"]
Find below code snippets for references
Step1:
Copy below code from main tf file.
provider "azurerm" {
features {}
}
variable "prefix" {
default = "rg_swar"
}
resource "azurerm_resource_group" "example" {
name = "rg_swar-resources"
location = "West Europe"
}
resource "azurerm_virtual_network" "example" {
name = "example-network"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
}
resource "azurerm_subnet" "service" {
name = "service"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
enforce_private_link_service_network_policies = true
}
resource "azurerm_subnet" "endpoint" {
name = "endpoint"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_public_ip" "example" {
name = "example-pip"
sku = "Standard"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
allocation_method = "Static"
}
resource "azurerm_lb" "example" {
name = "example-lb"
sku = "Standard"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
frontend_ip_configuration {
name = azurerm_public_ip.example.name
public_ip_address_id = azurerm_public_ip.example.id
}
}
resource "azurerm_private_link_service" "example" {
name = "example-privatelink"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
nat_ip_configuration {
name = azurerm_public_ip.example.name
primary = true
subnet_id = azurerm_subnet.service.id
}
load_balancer_frontend_ip_configuration_ids = [
azurerm_lb.example.frontend_ip_configuration.0.id,
]
}
resource "azurerm_api_management" "app" {
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
name = "swar-api-mgmt"
publisher_email = "test#demo.com"
publisher_name = "Swarna Demo"
sku_name = "Developer_1"
//tags = var.resource_tags
}
resource "azurerm_private_endpoint" "example" {
name = "example-endpoint"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
subnet_id = azurerm_subnet.endpoint.id
private_service_connection {
name = "example-privateserviceconnection"
//private_connection_resource_id = azurerm_private_link_service.example.id
private_connection_resource_id = azurerm_api_management.app.id
subresource_names = ["Gateway"]
is_manual_connection = false
}
}
Step2:
run below commands
terraform plan
terraform apply -auto-approve
Review:
Above code snippet will host the services into Azure Portal.
Hope this helps!

Call to function "merge" failed: arguments must be maps or objects, got "tuple"

I'm getting the below error which I'd appreciate some help with. I'm trying to add a bolt-on to a terraform public module to apply a best practice set of options in addition to any passed to the module in the usual way. What's the correct way of doing this please as I'm not certain that nesting my lookup function within a merge is valid.
terraform version = 1.1.12
provider version = hashicorp/aws 2.49
error message
│ Error: Error in function call
│
│ on ../modules/db_option_group/main.tf line 5, in locals:
│ 5: merged_options = merge(var.mysql_standard_options,var.options)
│ ├────────────────
│ │ var.mysql_standard_options is tuple with 1 element
│ │ var.options is empty tuple
│
│ Call to function "merge" failed: arguments must be maps or objects, got "tuple".
main.tf snippet
locals {
name = var.use_name_prefix ? null : var.name
name_prefix = var.use_name_prefix ? "${var.name}-" : null
merged_options = merge(lookup(var.option_group_map,var.engine_name),var.options) # error caused here
description = coalesce(var.option_group_description, format("%s option group", var.name))
}
resource "aws_db_option_group" "this" {
count = var.create ? 1 : 0
name = local.name
name_prefix = local.name_prefix
option_group_description = local.description
engine_name = var.engine_name
major_engine_version = var.major_engine_version
dynamic "option" {
# for_each = var.options
for_each = local.merged_options
content {
option_name = option.value.option_name
port = lookup(option.value, "port", null)
version = lookup(option.value, "version", null)
db_security_group_memberships = lookup(option.value, "db_security_group_memberships", null)
vpc_security_group_memberships = lookup(option.value, "vpc_security_group_memberships", null)
dynamic "option_settings" {
for_each = lookup(option.value, "option_settings", [])
content {
name = lookup(option_settings.value, "name", null)
value = lookup(option_settings.value, "value", null)
}
}
}
}
variables.tf snippet
variable "options" {
description = "A list of Options to apply"
type = any
default = []
}
variable "option_group_map" {
type = map
default = {
"mysql" = "var.mysql_standard_options"
"mariadb" = "var.mysql_standard_options"
"sqlserver-ee" = "var.sqlserver_standard_options"
"sqlserver-ex" = "var.sqlserver_standard_options"
"sqlserver-se" = "var.sqlserver_standard_options"
"sqlserver-web" = "var.sqlserver_standard_options"
"oracle-ee" = "var.oracle_standard_options"
"oracle-se2" = "var.oracle_standard_options"
}
}
variable "mysql_standard_options" {
description = "A list of DB options to apply for MySQL instances"
type = any
default = [
{
# For auditing of connection attempts.
option_name = "MARIADB_AUDIT_PLUGIN"
option_settings = [
{
name = "SERVER_AUDIT_EVENTS"
value = "CONNECT,QUERY_DDL"
},
{
name = "SERVER_AUDIT_FILE_ROTATIONS"
value = "35"
}
]
}
]
}
...
...
...
** --UPDATE 1-- **
I changed the brackets used from square brackets used for lists/tuples to curly braces in my variable definitions like so:
variable "options" {
description = "A list of Options to apply"
type = any
default = {}
}
variable "option_group_map" {
type = map
default = {
"mysql" = "var.mysql_standard_options"
"mariadb" = "var.mysql_standard_options"
"sqlserver-ee" = "var.sqlserver_standard_options"
"sqlserver-ex" = "var.sqlserver_standard_options"
"sqlserver-se" = "var.sqlserver_standard_options"
"sqlserver-web" = "var.sqlserver_standard_options"
"oracle-ee" = "var.oracle_standard_options"
"oracle-se2" = "var.oracle_standard_options"
}
}
variable "mysql_standard_options" {
description = "A list of DB options to apply for MySQL instances"
type = any
default = {
option1 = {
# For auditing of connection attempts.
option_name = "MARIADB_AUDIT_PLUGIN"
option_settings = {
option_setting_1a = {
name = "SERVER_AUDIT_EVENTS"
value = "CONNECT,QUERY_DDL"
},
option_setting_1b = {
name = "SERVER_AUDIT_FILE_ROTATIONS"
value = "35"
}
}
},
}
}
But still look to be getting issues with both variables passed to the merge function. Am now thinking maybe I need a for loop for this.
│ Error: Error in function call
│
│ on ../modules/db_option_group/main.tf line 4, in locals:
│ 4: merged_options = merge(lookup(var.option_group_map,var.engine_name),var.options)
│ ├────────────────
│ │ var.engine_name is "mysql"
│ │ var.option_group_map is map of string with 8 elements
│ │ var.options is empty tuple
│
│ Call to function "merge" failed: arguments must be maps or objects, got "string".
** --UPDATE 2-- **
If I add the "..." onto the end of the variable within the merge and remove the lookup it looks better I just need to work out a way to conditionally use a different variable depending upon the engine type.
-- from main.tf
#merged_options = merge(lookup(var.option_group_map,var.engine_name),var.options...)
merged_options = merge(var.mysql_standard_options,var.options...)
** --UPDATE 3-- **
Ok think I've sorted now by splitting up the option group blocks per engine type and amending the count type rather than doing a lookup
locals {
name = var.use_name_prefix ? null : var.name
name_prefix = var.use_name_prefix ? "${var.name}-" : null
merged_mysql_options = merge(var.mysql_standard_options,var.options...)
merged_postgres_options = merge(var.mysql_standard_options,var.options...)
merged_sqlserver_options = merge(var.mysql_standard_options,var.options...)
merged_oracle_options = merge(var.mysql_standard_options,var.options...)
description = coalesce(var.option_group_description, format("%s option group", var.name))
mysql_option = length(regexall(".*mysql*", var.engine_name)) > 0
postgres_option = length(regexall(".*postgres*", var.engine_name)) > 0
sqlserver_option = length(regexall(".*sqlserver*", var.engine_name)) > 0
oracle_option = length(regexall(".*oracle*", var.engine_name)) > 0
}
resource "aws_db_option_group" "mysql" {
count = var.create && local.mysql_option ? 1 : 0
name = local.name
name_prefix = local.name_prefix
option_group_description = local.description
engine_name = var.engine_name
major_engine_version = var.major_engine_version
dynamic "option" {
# for_each = var.options
for_each = local.merged_mysql_options
content {
option_name = option.value.option_name
port = lookup(option.value, "port", null)
version = lookup(option.value, "version", null)
db_security_group_memberships = lookup(option.value, "db_security_group_memberships", null)
vpc_security_group_memberships = lookup(option.value, "vpc_security_group_memberships", null)
dynamic "option_settings" {
for_each = lookup(option.value, "option_settings", [])
content {
name = lookup(option_settings.value, "name", null)
value = lookup(option_settings.value, "value", null)
}
}
}
}
tags = merge(
var.tags,
{
"Name" = var.name
},
)
timeouts {
delete = lookup(var.timeouts, "delete", null)
}
lifecycle {
create_before_destroy = true
}
}

terraform azure mysql gtid_mode "ON" error

i am trying to create mysql with some default configurations on azure with terraform, following is my code. although "enforce_gtid_consistency" and "time_zone" is working and being created, but "gtid_mode" "ON" isn't working I am getting following error.
resource "azurerm_mysql_server" "main" {
name = var.mysql_server_name != "" ? var.mysql_server_name : "mysql-01-${var.instancesuffix}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
administrator_login = var.mysql_administrator_login
administrator_login_password = data.mykv.mysql.value
sku_name = var.mysql_sku_name
storage_mb = var.mysql_storage_mb
version = var.mysql_version
auto_grow_enabled = true
backup_retention_days = 7
geo_redundant_backup_enabled = false
infrastructure_encryption_enabled = true
public_network_access_enabled = true
ssl_enforcement_enabled = true
ssl_minimal_tls_version_enforced = "TLS1_2"
lifecycle {
ignore_changes = [tags]
}
threat_detection_policy {
disabled_alerts = []
email_account_admins = false
email_addresses = []
enabled = true
retention_days = 0
}
}
resource "azurerm_mysql_configuration" "time_zone" {
name = "time_zone"
resource_group_name = azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
value = "+00:00"
}
resource "azurerm_mysql_configuration" "enforce_gtid_consistency" {
name = "enforce_gtid_consistency"
resource_group_name = azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
value = "ON"
}
resource "azurerm_mysql_configuration" "gtid_mode" {
name = "gtid_mode"
resource_group_name = azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
value = "ON"
}
Error: waiting for creation of Configuration: (Name "gtid_mode" / Server Name "mysql-01" / Resource Group "myrg-01"): Code="InternalServerError" Message="An unexpected error occured while processing the request. Tracking ID: 'h59fr7f-18uo-90db-tb20-5y65d34btb04'"
on resources.tf line 164, in resource "azurerm_mysql_configuration" "gtid_mode":
164: resource "azurerm_mysql_configuration" "gtid_mode" {
As I have mentioned in comment , The gtid_mode can only be enabled in sequence , directly turning ON will not work evenif the dependency is set with enforce_gtid_consistency.
So, as a solution you have to set it up in sequence:
OFF_PERMISSIVE
ON_PERMISSIVE
ON
I tested with your code doing some changes as below:
main.tf
provider "azurerm"{
features{}
}
data "azurerm_resource_group" "main"{
name = "resourcegroup"
}
data "azurerm_key_vault" "kv"{
name = "ansumantestkv1234"
resource_group_name = "resourcegroup"
}
data "azurerm_key_vault_secret" "name" {
name = "mysqlpassword"
key_vault_id = data.azurerm_key_vault.kv.id
}
resource "azurerm_mysql_server" "main" {
name = var.mysql_server_name
location = data.azurerm_resource_group.main.location
resource_group_name = data.azurerm_resource_group.main.name
administrator_login = var.mysql_administrator_login
administrator_login_password = data.azurerm_key_vault_secret.name.value
sku_name = var.mysql_sku_name
storage_mb = var.mysql_storage_mb
version = var.mysql_version
auto_grow_enabled = true
backup_retention_days = 7
geo_redundant_backup_enabled = false
infrastructure_encryption_enabled = true
public_network_access_enabled = true
ssl_enforcement_enabled = true
ssl_minimal_tls_version_enforced = "TLS1_2"
threat_detection_policy {
disabled_alerts = []
email_account_admins = false
email_addresses = []
enabled = true
retention_days = 0
}
}
resource "azurerm_mysql_configuration" "time_zone" {
name = "time_zone"
resource_group_name = data.azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
value = "+00:00"
}
resource "azurerm_mysql_configuration" "enforce_gtid_consistency" {
name = "enforce_gtid_consistency"
resource_group_name = data.azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
value = "ON"
depends_on = [
azurerm_mysql_configuration.time_zone
]
}
resource "azurerm_mysql_configuration" "gtid_mode_OFF_permissive" {
name = "gtid_mode"
resource_group_name = data.azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
value = "OFF_PERMISSIVE"
depends_on = [
azurerm_mysql_configuration.enforce_gtid_consistency,
]
}
resource "azurerm_mysql_configuration" "gtid_mode_ON_Permissive" {
name = "gtid_mode"
resource_group_name = data.azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
value = "ON_PERMISSIVE"
depends_on = [
azurerm_mysql_configuration.gtid_mode_OFF_permissive
]
}
resource "azurerm_mysql_configuration" "gtid_mode_ON" {
name = "gtid_mode"
resource_group_name = data.azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
value = "ON"
depends_on = [
azurerm_mysql_configuration.gtid_mode_ON_Permissive
]
}
variable.tf:
variable "mysql_server_name" {
default = "ansumanmysqlserver"
}
variable "mysql_administrator_login" {
default = "ansuman"
}
variable "mysql_sku_name" {
default = "GP_Gen5_2"
}
variable "mysql_storage_mb" {
default = "5120"
}
variable "mysql_version" {
default = "5.7"
}
Outputs:
Reference:
MySQL :: MySQL 8.0 Reference Manual :: 17.1.4.2 Enabling GTID Transactions Online

Add custom DNS Server IP to an Azure VM NIC using Terraform

How to point to custom DNS IP using terraform IP Configuration block, sample code show below, is this valid?
resource "azurerm_network_interface" "example" {
name = "example-nic"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
dns_servers = 8.8.8.8,8.8,8.8
}
}
as per terraform documentation
resource "azurerm_network_interface" "example" {
name = "example-nic"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
dns_servers = ["8.8.8.8","1.1.1.1"]
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
}
}

Parse Bloomberg API response to JSON in python3

How can I convert the response message that returned from using bloomberg API in (python3 and flask) in to JSON
here is a response example:
ReferenceDataResponse = {
securityData[] = {
securityData = {
security = "FB EQUITY"
eidData[] = {
}
fieldExceptions[] = {
}
sequenceNumber = 0
fieldData = {
PX_LAST = 186.270000
VOLUME = 16746904.000000
}
}
securityData = {
security = "IBM EQUITY"
eidData[] = {
}
fieldExceptions[] = {
}
sequenceNumber = 1
fieldData = {
PX_LAST = 134.400000
VOLUME = 2551009.000000
}
}
}
}
dealing with it with the comming piece of code :
if str(msg.messageType()) == "ReferenceDataResponse":
securities = msg.getElement('securityData')
securities_count = securities.numValues()
for i in range(securities_count):
security = securities.getValueAsElement(i)
ticker = security.getElementAsString('security')
if (security.hasElement('fieldData')):
fields = security.getElement('fieldData')
fields_count = fields.numElements()
for j in range (fields_count):
security_dict = None
field = fields.getElement(j)
f_name = field.name()
f_value = field.getValueAsString()
security_dict = {"ticker":ticker ,"f_name":f_name , "f_value":f_value}
bloom_data.append(security_dict)
give me (Object of type Name is not JSON serializable)
now, I cant not access the name object to reach the name of the fields
any help will be very appreciated
After a lot of search I found this doc that is very helpful for as a schema for using the bloomberg api for dealing with the response ....
Here's the link ==> api schema
example for handeling respnse using python3:
bloom_data = []
if str(msg.messageType()) == "ReferenceDataResponse":
securities = msg.getElement('securityData')
securities_count = securities.numValues()
for i in range(securities_count):
security = securities.getValueAsElement(i)
ticker = security.getElementAsString('security')
if (security.hasElement('fieldData')):
fields = security.getElement('fieldData')
fields_count = fields.numElements()
for j in range (fields_count):
security_dict = None
field = fields.getElement(j)
f_name = field.name()
f_value = field.getValueAsString()
security_dict = {"ticker":ticker ,"f_name":str(f_name) , "f_value":f_value}
bloom_data.append(security_dict)