Reputation: 1740
I want to create azurerm_mssql_firewall_rule
resource witch allows IP of "Azure windows web app".
When I write it manually it works fine. f.e.:
resource "azurerm_mssql_firewall_rule" "api_cloud" {
name = var.cloud_firewal_rule_name
server_id = azurerm_mssql_server.api.id
start_ip_address = "00.000.000.00"
end_ip_address = "00.000.000.00"
}
I want to get IP address like this start_ip_address/end_ip_address = azurerm_windows_web_app.api.inbound_ip_address
.
But there isn't inbound option in azurerm_windows_web_app
, I can only access outbound addresses azurerm_windows_web_app.api.outbound_ip_addresses
.
Is there is anyway do something like this?
IN SHORT:
How to get this IP address with terraform?
Upvotes: 0
Views: 927
Reputation: 556
Yes, there is but it's a bit complicated due to the way Terraform works. I used a Linux App Service in my examples but it should work identically for both Windows and Linux versions. Let's go:
So, things are a bit more complicated due to the fact that App Services have quite a big range of possible outbound IP addresses as they are running on a shared infrastructure. Therefore it returns a list with an unknown length. That makes things annoying for Terraform. As an example, this is how you usually iterate through multiple items in Terraform using for_each:
resource "azurerm_mssql_firewall_rule" "example" {
for_each = toset(azurerm_linux_web_app.api_app.outbound_ip_address_list)
name = "FirewallRule"
server_id = azurerm_mssql_server.example.id
start_ip_address = each.key
end_ip_address = each.key
}
In this snippet, you take the list of outbound IP addresses from the App Service, cast them to a set, and then iterate through it. However, this only works if the App Service already exists - if you are starting from an empty slate, you will face the following error:
azurerm_linux_web_app.api_app.outbound_ip_address_list is a list of string, known only after apply
The "for_each" map includes keys derived from resource attributes that cannot be determined until apply, and so Terraform cannot determine the full set of keys that will identify the instances of this resource.
When working with unknown values in for_each, it's better to define the map keys statically in your configuration and place apply-time results only in the map values.
Alternatively, you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge.
Luckily Terraform has a quite helpful error message, which tells us how we can work around the problem. Using the -target parameter we can first create the App Service like this
terraform apply -target=azurerm_linux_web_app.api_app
This should only create the App Service and dependencies required by it. Afterward, we can then execute Terraform normally and it should work as desired without any errors. It's not very pretty, but currently, there are no better ways of achieving exactly what you want.
Upvotes: 1