I am having below bicep which is returning keyvault. I like to access the properties/functions in keyvault in parent bicep. But not sure how to achieve when using it as a module.
I have keyvault.bicep
resource kv 'Microsoft.KeyVault/vaults#2019-09-01' existing = {
name: kvName
scope: resourceGroup(subscriptionId, kvResourceGroup )
}
output kv1 object=kv
I have parent.bicep (where keyvault.bicep is included as module)
module kv './keyvault.bicep' = {
name: 'get Secrets'
params: {
subscriptionId: subscriptionId
kvResourceGroup: resourceGroupName
kvName: keyVaultName
}
}
var pwd= kv.outputs.kv1.getSecret('key')
but getSecret method is unknown in parent bicep
Kindly suggest how to proceed?
The short answer is that is not supported.
In your parent.bicep file, kv is a module reference, not a resource. In order to correctly understand the parent-child resource hierarchy, Bicep requires a resource reference of the correct parent type in the parent property value.
Tho there is a proposal to simplify resource referencing:
https://github.com/Azure/bicep/issues/2246
Let say you have keyvault.bicep module that creates a key vault
resource kv 'Microsoft.KeyVault/vaults#2019-09-01' = {
name: kvName
...
}
output name string = kv.name
In the parent.bicep, you could get a reference to key vault like that:
module kvModule './keyvault.bicep' = {
name: 'key-vault-${keyVaultName}'
params: {
kvName: keyVaultName
...
}
}
resource kv 'Microsoft.KeyVault/vaults#2019-09-01' existing = {
name: kvModule.outputs.name
}
In you example, there are few things:
The key vault module just gets a reference to key vault so you don't really need a module, you could just reference the key vault directly in the parent.bicep file.
The getSecret function is a really specific function, you can only use it to pass secure parameter to another module:
Returns a secret from an Azure Key Vault. The getSecret function can only be called on a Microsoft.KeyVault/vaults resource. Use this function to pass a secret to a secure string parameter of a Bicep module. The function can be used only with a parameter that has the #secure() decorator.
Related
I am deploying an App Gateway on Azure using a Bicep template (relevant pieces shown below).
var applicationGatewayId = resourceId('Microsoft.Network/applicationGateways', applicationGatewayName)
resource applicationGateway 'Microsoft.Network/applicationGateways#2021-08-01' = {
properties: {
urlPathMaps: [
{
properties: {
defaultBackendAddressPool: {
id: '${applicationGatewayId}/backendAddressPools/backendpool-test'
}
}
]
}
}
My question is about the id of the backendAddressPool in the example. I get a warning when compiling: Warning use-resource-id-functions: If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, reference, resourceId, subscription, subscriptionResourceId, tenantResourceId. [https://aka.ms/bicep/linter/use-resource-id-functions].
I tried using ${applicationGateway.id}/backendAddressPools/backendpool-test, but that results in a cyclic reference error. For other resource types I used resourceId(), but for this example I wouldn't know how to.
I tried, e.g., resourceId('Microsoft.Network/ApplicationGatewayBackendAddressPool', '${prefix}-backendpool-infocat'), but that seems to result in a different resource type altogether (doesn't compile into the same id, at least).
This question is applicable to other subresources too, such as:
applicationGateway.urlPathMaps.defaultBackendAddressPool
applicationGateway.urlPathMaps.pathRules.backendAddressPool
applicationGateway.urlPathMaps.pathRules.backendHttpSettings
...
So how does one refer to these subresources properly, when there's no readily defined resourceType to be used in resourceId()? Can the warnings be avoided?
Thanks in advance!
Try this:
id:resourceId('Microsoft.Network/applicationGateways/backendAddressPools', applicationGatewayName, applicationGatewayBackendAddressPoolName)
New to terraform, and have been building out the infrastructure recently.
I am trying to pull secrets from azure key vault and assign the keys to the variables.tf file depending on the environment(dev.tfvars, test.tfvars, etc). However when I execute the plan with the tfvar file as the parameter, I get an error with the following message:
Error: Variables not allowed
Here are the files and the relevant contents of it.
variables.tf:
variable "user_name" {
type = string
sensitive = true
}
data.tf (referencing the azure key vault):
data "azurerm_key_vault" "test" {
name = var.key_vault_name
resource_group_name = var.resource_group
}
data "azurerm_key_vault_secret" "test" {
name = "my-key-vault-key-name"
key_vault_id = data.azurerm_key_vault.test.id
}
test.tfvars:
user_name = "${data.azurerm_key_vault_secret.test.value}" # Where the error occurrs
Can anyone point out what I'm doing wrong here? And if so is there another way to achieve such a thing?
In Terraform a variable can be used for user input only. You can not assign to them anything dynamically computed from your code. They are like read-only arguments, for more info see Input Variables from the doc.
If you want to assign a value to something for later use, you must use locals. For example:
locals {
user_name = data.azurerm_key_vault_secret.test.value
}
Local values can be changed dynamically during execution. For more info, see Local Values.
You can't create dynamic variables. All variables must have known values before execution of your code. The only thing you could do is to use local, instead of variabile:
locals {
user_name = data.azurerm_key_vault_secret.test.value
}
and then refer to it as local.user_name.
I'm running bicep 0.4.1318.
I have a "main" bicep module that calls a sub module to provision data factory:
var adfName = 'adf-ctaxrebate-${envPlusSuffix}-${formattedInstanceNum}'
module adfDeploy 'CTaxRebate.dataFactory.bicep' = {
name: 'adfDeploy'
params: {
adfName: adfName
}
}
The data factory module is as follows:
param adfName string
resource adf 'Microsoft.DataFactory/factories#2018-06-01' = {
name:adfName
location: resourceGroup().location
}
output dfId string = adf.identity.principalId
I used the PowerShell cdmlet New-AzResourceGroupDeployment to run the main bicep but I'm getting the following error:
The template output 'dfId' is not valid: The language expression
| property 'identity' doesn't exist, available properties are 'apiVersion, location, tags, etc...
I think this is trying to tell me that the following line from the adf module is wrong:
output dfId string = adf.identity.principalId
I'm puzzled by this since I've used the same code on a previous project and it works ok.
Also, the identity property does appear in the intellisense:
You need to add
identity: {
type: 'SystemAssigned'
}
to the definition of your DataFactory in the module to tell the system it should generate a system assigned ID for you.
I am using a Bicep script to create resources in Mcirosoft Azure.
I have defined a variable with the common tags that are the same for all resources.But now, when assigning this variable to a resource, I want to add more tags that are only for this resource.
However, I have not yet found a way to do this.
You can use the union function to merge object.
In this sample, I've defined a parameter with the common tags and merge the object with resource specific tags:
param commonTags object = {
commonTag1: 'commonTag1'
commonTag2: 'commonTag2'
}
resource storageAccount 'Microsoft.Storage/storageAccounts#2019-06-01' = {
name: 'my storage account name'
...
tags: union(commonTags, {
storageTag1: 'storageTag1'
storageTag2: 'storageTag2'
})
}
I have defined the following Terraform module:
module "lambda" {
source = "../lambda"
region = "us-west-1"
account = "${var.account}"
}
How can I take advantage from the module name to set the source parameter with an interpolation? I wish something like:
module "lambda" {
source = "../${this.name}"
region = "us-west-1"
account = "${var.account}"
}
locals {
module = basename(abspath(path.module))
}
{
...
some-id = local.module
...
}
I think is not possible. There's a self that allows you to reference attributes within your resource, but the identifier is not an attribute. Also, self is only allowed within provisioners.
I guess the only way to accomplish what you want is templating the .tf files, like:
module {{ my-module}} {
source = "../{{ my-module }}"
region = "us-west-1"
account = "${var.account}"
but you should render the templates before terraform init. It's straightforward to setup in a CI pipeline, but I find it cumbersome when working locally.