I created a Multi-instance mobile app pipeline. It creates an apk and an aab per tenant (client). To do so I make use of a pipeline parameter where I can set multiple tenants at a time:
- name: Tenants
displayName: "Select Tenants to build for"
type: object
default:
- ExampleClient
- ExampleClient2
Now in the BuildAndroid stage I want to build an .apk and .aab per tenant which I use a matrix for and a compile time for loop:
- stage: BuildAndroid
variables:
- group: ${{ TenantName }}
jobs:
- job: 'BuildAndroid'
strategy:
matrix:
${{ each tenant in parameters.Tenants }}:
${{ format('{0}_APK', tenant) }}:
TenantName: ${{ tenant }}
BuildFormat: 'apk'
SignAndroid: $(SignAndroidApk)
BuildApp: $(PackageAndroidApk)
${{ format('{0}_AAB', tenant) }}:
TenantName: ${{ tenant }}
BuildFormat: 'aab'
SignAndroid: $(SignAndroidAab)
BuildApp: $(PackageAndroidAab)
displayName: 'Build Android'
"- group: ${{ TenantName }}" is responsible for setting the tenant-specific variables and secrets but TenantName is not available because it's part of the matrix for loop. Variable groups can't be set dynamically at runtime using $() syntax. So how can I go about this?
(Line: 53, Col: 12): Unrecognized value: 'TenantName'. Located at position 1 within
expression: TenantName.
What I expect: I can select multiple tenants before the pipeline runs and it builds the apk and aab for all selected tenants based on tenant specific variables and secrets.
How can I change my approach to make this work?
Assuming you would expect to reference variable groups dynamically with the group names of ${{ TenantName }}
, whose names are the same values as those defined in parameters.Tenants
, the sample below works. As required, you can also define multiple tenants for parameters.Tenants
at queue time and pipeline jobs will be expanded for each
value in parameters.Tenants
and matrix with values retrieved from respective variable group.
parameters:
- name: Tenants
displayName: "Select Tenants to build for"
type: object
default:
- ExampleClient1
- ExampleClient2
stages:
- stage: BuildAndroid
jobs:
- ${{ each tenant in parameters.Tenants }}:
- job: 'BuildAndroid_${{ tenant }}'
dependsOn: []
displayName: 'Build Android for ${{ tenant }}'
variables:
- group: ${{ tenant }}
strategy:
matrix:
${{ format('{0}_APK', tenant) }}:
TenantName: ${{ tenant }}
BuildFormat: 'apk'
SignAndroid: $(SignAndroidApk)
BuildApp: $(PackageAndroidApk)
${{ format('{0}_AAB', tenant) }}:
TenantName: ${{ tenant }}
BuildFormat: 'aab'
SignAndroid: $(SignAndroidAab)
BuildApp: $(PackageAndroidAab)
steps:
- script: |
echo "TenantName: $(TenantName)"
echo "BuildFormat: $(BuildFormat)"
echo "SignAndroid: $(SignAndroid)"
echo "BuildApp: $(BuildApp)"