Introduction
When deploying applications and infrastructure there are times when executing PowerShell is required as part of our Continuous Integration (CI) and Continuous Deployment (CD) Pipelines. There are two suggested ways to accomplish this. Either write the PowerShell inline of the ADO task or execute by passing in the path of the script. This post will cover passing a PowerShell file via the PowerShell ADO task. This task will be configured as a template to improve future usability.
When to Use
This task is to be used in YAML Pipelines. YAML pipelines are preferred to classic releases as the task steps will be defined as .yml
file type and stored in Git. For this specific purpose I needed to run the PowerShell script which is part of Azure Data Factories deployment to stop and start triggers.
Seeing the script needed to be ran twice, I naturally created a task template to handle the execution. Additionally this task was templated to run any PowerShell script which is part of the artifact deployment.
Layout
This task template is stored in a centralized repository, in this case TheYAMLPipelineOne on GitHub. This task requires the PowerShell script be published as part of the artifact deployment. Publishing the script as part of the deployment as an artifact is a recommend practice as it will ensure the script that is deployed is retained as part of the pipeline and can be used across multiple stages.
The Template
Here is the PowerShell task template:
parameters:
- name: azureSubscriptionName
type: string
- name: scriptPath
type: string
- name: ScriptArguments
type: string
default: ''
- name: errorActionPreference
type: string
default: 'stop'
- name: FailOnStandardError
type: boolean
default: false
- name: azurePowerShellVersion
type: string
default: 'azurePowerShellVersion'
- name: preferredAzurePowerShellVersion
type: string
default: '3.1.0'
- name: pwsh
type: boolean
default: false
- name: workingDirectory
type: string
- name: displayName
type: string
default: 'Running Custom Azure PowerShell script from file'
steps:
- task: AzurePowerShell@5
displayName: ${{ parameters.displayName }}
inputs:
scriptType: 'FilePath'
ConnectedServiceNameARM: ${{ parameters.azureSubscriptionName }}
scriptPath: ${{ parameters.scriptPath }}
ScriptArguments: ${{ parameters.ScriptArguments }}
errorActionPreference: ${{ parameters.errorActionPreference }}
FailOnStandardError: ${{ parameters.FailOnStandardError }}
azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
pwsh: ${{ parameters.pwsh }}
workingDirectory: ${{ parameters.workingDirectory }}
This task just requires the script path and the service connection. These are really the two things that can vary within a pipeline at a bare minimum. The rest of these parameters have been defaulted to the values associated with the task documentation. This is done to provide flexibility to override these values by any consuming template.
For an example of how to call this one can look at the adf_deploy_env_job.yml file on TheYAMLPipelineOne repository. One can check out the complete template by visiting the repository.
- template: ../tasks/azpwsh_file_execute_task.yml
parameters:
azureSubscriptionName: ${{ variables.azureServiceConnectionName }}
scriptPath: ${{ variables. powerShellScriptPath }}
ScriptArguments: '-armTemplate "${{ variables.ARMTemplatePath }}" -ResourceGroupName ${{ variables.resourceGroupName }} -DataFactoryName ${{ variables.dataFactoryName }} -predeployment $true -deleteDeployment $false'
displayName: 'Stop ADF Triggers'
workingDirectory: ${{ parameters.workingDirectory }}
The Result
When this task executes, in this case, it will leverage the file PrePostDeploymentScript.ps1
Here is the pipeline job results:
Conclusion
This is a pretty basic example of how I template up my YAML deployments. This PowerShell template task is generic enough that it should provide flexibility for any PowerShell files one may want to execute as part of their deploments.
For information on this feel free to check out my other YAML Pipeline posts.