i'm trying to create an Azure DEvOps pipeline that deploy a VM using terraform, and then connect to that VM using WinRm to execute script but i can't find a way to pass the Public IP captured from output.tf to the pipeline to be used on the connection. Hope somebody can give some advice to solve this problem.
See below my .yml file
trigger:
none
pool:
vmImage: 'windows-latest'
variables:
bkrg: 'CloudOPs_OPS_RG'
bkstorage: 'xxxxxxxxxx'
bkcontainer: 'terraformmtp'
bkkey: 'terraform.tfstate'
adminUsername: 'xxxxxxxxxxxx'
adminPassword: 'xxxxxxxxxxxxx'
parameters:
- name: bacpacSasToken
displayName: 'Bacpac SAS Token'
type: string
stages:
- stage: 'tfvalidate'
jobs:
- job: 'validate'
continueOnError: false
steps:
- task: TerraformInstaller@0
displayName: 'Install Terraform'
inputs:
terraformVersion: 'latest'
- task: TerraformTaskV3@3
displayName: 'Terraform init'
inputs:
provider: 'azurerm'
command: 'init'
backendServiceArm: 'xxxxxxxxxxxxxxxx'
backendAzureRmResourceGroupName: '$(bkrg)'
backendAzureRmStorageAccountName: '$(bkstorage)'
backendAzureRmContainerName: '$(bkcontainer)'
backendAzureRmKey: '$(bkkey)'
- task: TerraformTaskV3@3
displayName: 'Terraform validate'
inputs:
provider: 'azurerm'
command: 'validate'
- stage: 'tfdeploy'
condition: succeeded('tfvalidate')
dependsOn: 'tfvalidate'
jobs:
- job: 'apply'
steps:
- task: TerraformInstaller@0
displayName: 'Install Terraform'
inputs:
terraformVersion: 'latest'
- task: TerraformTaskV3@3
displayName: 'Terraform init'
inputs:
provider: 'azurerm'
command: 'init'
backendServiceArm: 'xxxxxxxxxxxxxxxx'
backendAzureRmResourceGroupName: '$(bkrg)'
backendAzureRmStorageAccountName: '$(bkstorage)'
backendAzureRmContainerName: '$(bkcontainer)'
backendAzureRmKey: '$(bkkey)'
- task: TerraformTaskV3@3
displayName: 'Terraform plan'
inputs:
provider: 'azurerm'
command: 'plan'
environmentServiceNameAzureRM: 'xxxxxxxxxxxxxxxx'
- task: TerraformTaskV3@3
displayName: 'Terraform apply'
inputs:
provider: 'azurerm'
command: 'apply'
environmentServiceNameAzureRM: 'xxxxxxxxxxxxxxxx'
- task: PowerShell@2
displayName: 'Capture public IP and push to pipeline variable'
inputs:
targetType: 'inline'
script: |
$tfOutput = terraform output -json | ConvertFrom-Json
$publicIp = $tfOutput.public_ip.value
Write-Host "##vso[task.setvariable variable=publicIp;isOutput=true]$publicIp"
Write-Host "Captured Public IP: $publicIp"
- stage: 'bacpacoperations'
condition: succeeded('tfdeploy')
dependsOn: 'tfdeploy'
jobs:
- job: 'downloadbacpac'
variables:
public_ip: $[ stageDependencies.tfdeploy.apply.outputs['publicIp'] ]
steps:
- task: AzureCLI@2
displayName: 'Azure CLI'
inputs:
azureSubscription: 'xxxxxxxxxxxxxxxx'
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
$publicip = "$(public_ip)"
$username = "$(adminUsername)"
$password = "$(adminPassword)"
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($username, $securePassword)
$session = New-PSSession -ComputerName $publicip -Credential $credential -UseSSL -Port 5986
Invoke-Command -Session $session -ScriptBlock {
cd $(System.DefaultWorkingDirectory)
./downloadbacpac.ps1 -bacpacSasToken "$(bacpacSasToken)" -localPath "f:\\"
}
Remove-PSSession -Session $session
this is the error i'm getting
New-PSSession : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an
argument that is not null or empty, and then try the command again.
At D:\a\_temp\azureclitaskscript1726051757039_inlinescript.ps1:6 char:40
+ $session = New-PSSession -ComputerName $publicip -Credential $credent ...
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [New-PSSession], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.NewPSSessionCommand
##[error]Script failed with exit code: 1
To use variable in next stage
, please add task name
in the powershell task in tfdeploy
stage.
- task: PowerShell@2
displayName: 'Capture public IP and push to pipeline variable'
name: getip # <-- add task name
inputs:
targetType: 'inline'
script: |
$tfOutput = terraform output -json | ConvertFrom-Json
$publicIp = $tfOutput.public_ip.value
Write-Host "##vso[task.setvariable variable=publicIp;isOutput=true]$publicIp"
Write-Host "Captured Public IP: $publicIp" # < -- make sure ip value output is correct
And in next stage, include the task name in variable expression:
variables:
public_ip: $[ stageDependencies.tfdeploy.apply.outputs['getip.publicIp'] ]
Please refer to the doc Use outputs in a different stage for the details.
In powershell task, please make sure the agent ip $publicIp
is correctly output, as the value will be set as the output variable value to next stage.