Steve Button
Steve Button

Reputation: 97

Passing an object into a template in Azure DevOps pipeline

I'm trying to refactor an Azure DevOps job which runs on about 100 accounts, currently these are individual tasks in the pipeline which are almost identical. They happen to call some Cloud Formation in AWS, but that's not really important.

I want to have a template parameter in the pipeline something like :-

parameters:
- name: stackparams
  type: object
  default:
    - displayname: AWS Test User Account
      awscredentials: TESTAWS-appaccounttest1-AzureDevOps
      templatefile: ./Test/TestApp/SwitchRolesGroupsPolicies.yml
      templateparametersfile: ./Test/LZTestApp/demoparams.json
    - displayname: Second Account
      awscredentials: TESTAWS-appaccounttest2-AzureDevOps
      templatefile: ./Test/Something/SwitchRolesGroupsPolicies.yml
      templateparametersfile: ./Test/Something/demoparams.json

And in the template something like :-

parameters:
- name: stackparams
  type: object

steps:
- ${{ each stackparam in parameters.stackparams }}:
  - checkout: self
  - task: AWSShellScript@1
    inputs:
      awsCredentials: ${{ stackparams.awscredentials }}
      regionName: 'eu-west-1' 
      scriptType: 'inline'
      inlineScript: |
        echo "\$STACKPARAMS_DISPLAYNAME: $STACKPARAMS_DISPLAYNAME"
    displayName: 'This is a test - ${{ stackparams.displayname }}'

However, I don't know if that's even possible and there's scant little documentation about doing it this way. I have replaced the Cloud Formation with just an AWSShellScript for the time being, just for a proof of concept. The error I'm currently getting is :-

> /Templates/CfnUpdateStack/CfnUpdateStack.yml (Line: 25, Col: 23):
> Unrecognized value: 'stackparams'. Located at position 1 within
> expression: stackparams.awscredentials. For more help, refer to
> https://go.microsoft.com/fwlink/?linkid=842996
> /Templates/CfnUpdateStack/CfnUpdateStack.yml (Line: 33, Col: 18):
> Unrecognized value: 'stackparams'. Located at position 48 within
> expression: format('Collect Cost Optimisation Data - {0}',
> stackparams.displayname). For more help, refer to
> https://go.microsoft.com/fwlink/?linkid=842996
> /Templates/CfnUpdateStack/CfnUpdateStack.yml (Line: 25, Col: 23):
> Unrecognized value: 'stackparams'. Located at position 1 within
> expression: stackparams.awscredentials. For more help, refer to
> https://go.microsoft.com/fwlink/?linkid=842996
> /Templates/CfnUpdateStack/CfnUpdateStack.yml (Line: 33, Col: 18):
> Unrecognized value: 'stackparams'. Located at position 48 within
> expression: format('Collect Cost Optimisation Data - {0}',
> stackparams.displayname). For more help, refer to
> https://go.microsoft.com/fwlink/?linkid=842996

Upvotes: 6

Views: 6413

Answers (1)

Levi Lu-MSFT
Levi Lu-MSFT

Reputation: 30313

Yes It is possible. And you are almost there. There is a small mistake in your template. ${{ stackparams.awscredentials }} should be ${{ stackparam.awscredentials }}.

And If you are using the same source repo, There is no need to include - checkout: self in the loop. For the tasks are run in the same job. The source repo can only checkout once. See below full example:

#azure-pipeline.yaml

parameters:
- name: stackparams
  type: object
  default:
    - displayname: AWS Test User Account
      awscredentials: TESTAWS-appaccounttest1-AzureDevOps
      templatefile: ./Test/TestApp/SwitchRolesGroupsPolicies.yml
      templateparametersfile: ./Test/LZTestApp/demoparams.json
    - displayname: Second Account
      awscredentials: TESTAWS-appaccounttest2-AzureDevOps
      templatefile: ./Test/Something/SwitchRolesGroupsPolicies.yml
      templateparametersfile: ./Test/Something/demoparams.json

trigger: none
pool: 
  vmImage: windows-latest

steps:
- template: stepsTemplate.yml
  parameters:
    stackparams: ${{parameters.stackparams}}  #pass the parameters to template parameters

--

#stepsTemplate.yml

parameters:
- name: stackparams
  type: object

steps:
- ${{ each stackparam in parameters.stackparams }}:
  
  - task: AWSShellScript@1
    inputs:
      awsCredentials: ${{ stackparam.awscredentials }}
      regionName: 'eu-west-1' 
      scriptType: 'inline'
      inlineScript: |
        echo "\$STACKPARAMS_DISPLAYNAME: $STACKPARAMS_DISPLAYNAME"
    displayName: 'This is a test - ${{ stackparam.displayname }}'

Upvotes: 4

Related Questions