It looks like the Azure provider represents that identity
block as a list when we refer to it in expressions. Knowing that, we can write an expression that produces a flat list of principle ids by visiting all of the identity
blocks across all of the app service instances, which is two levels of list:
output "ApiAppPrincipalId" {
value = flatten([
for identity in azurerm_app_service.apiApp[*].identity : identity[*].principal_id
])
}
The above uses several different Terraform expression features, so I'll break it down into smaller parts to explain:
azurerm_app_service.apiApp[*].identity
retrieves the identity
attribute for each of the app service instances, producing a list of results. As noted above, the identity
block seems to be represented as a list, so the result of this expression is a list of lists of objects describing the contents of each identity
block.
- The
[ for ... : ... ]
expression produces a new list by visiting each element of the given list (in this case, the result of the previous expression) and evaluating the expression after the :
(the result expression) against it. Because this is a list of lists of objects, identity
in the result expression is a list of objects.
identity[*].principal_id
retrieves the principal_id
attribute of each of the objects representing identity
blocks, again producing a list of results. In this case, because principal_id
is a string attribute, the result is a list of strings.
- The
flatten(...)
function deals with the fact that our for ....
expression alone would return a list of lists of strings. flatten
transforms that result into a flat list of strings by discarding the intermediate list nesting. The result is all of the principal_id
values across all of the identity
across all of the app service instances.
This is not directly related to your question, but note that it's idiomatic style in Terraform to name objects using underscore-separated words, like api_app_principal_id
rather than ApiAppPrincipalId
. It's also conventional to use a plural name for a collection value, like api_app_principal_ids
instead of api_app_principal_id
.
The naming doesn't affect Terraform's functionality here, of course, but using consistent naming can be helpful if you mix your own Terraform modules with modules written by other people, and improve the usability of your modules for those who are already familiar with Terraform from using it elsewhere.
output "api_app_principal_ids" {
value = flatten([
for identity in azurerm_app_service.api_app[*].identity : identity[*].principal_id
])
}
var.apiName
is an empty string. – Matt SchuchardapiName
. – Charles Xu