Reputation: 777
So this issue is a bit convoluted but I need this for a very specific case in azure. I'm trying to create an APIM subnet inside an azure k8s vnet, but I haven't been able to find a return value from the k8s terraform call that gives me the ID/name for the vnet. Instead I used a powershell command to query Azure and get the name of the new vnet. I was working on this code locally on my windows box and it works fine:
data "external" "cluster_vnet_name" {
program = [var.runPSVer6 == true ? "pwsh" : "powershell","Select-AzSubscription '${var.subscriptionName}' |out-null; Get-AzVirtualNetwork -ResourceGroupName '${module.kubernetes-service.k8ResourceGroup}' | Select Name | convertto-json}"]
depends_on = [module.kubernetes-service]
}
I have a toogle in my variables for runpsver6 so when I run on a linux machine it will change powershell to pwsh. Now, this is were is starts getting a little weird. When I run this on my windows machine, its not an issue, however when I run this from a linux box I get the following error:
can't find external program "pwsh"
I have tried a number of different work arounds (such as using the full powershell snapin path /snap/bin/powershell and putting the commands in a .ps1 file) to no avail. Every single time it throws the error that it can't find pwsh as an external program.
I use this same runPSVer6 toggle for local-exec terraform commands with no issue, but I need the name of the Vnet as a response.
Anyone have any ideas what I'm missing here?
ADDED AFTER SEPT 30th
So I tried the alternative way of firing commands:
variable "runPSVer6" {
type = bool
default = true
}
variable "subscriptionName" {
type = string
}
variable "ResourceGroup" {
type = string
}
data "external" "runpwsh" {
program = [var.runPSVer6 == true ? "pwsh" : "powershell", "test.ps1"]
query = {
subscriptionName = var.subscriptionName
ResourceGroup = var.ResourceGroup
}
}
output "vnet" {
value = data.external.runpwsh.result.name
}
and this appears to allow the command to execute, however its not pulling back the result of the json response (even when I confirmed that I do get a response).
This is what I'm using for my .ps1:
Param($subscriptionName,$ResourceGroup)
$subscription = Select-AzSubscription $subscriptionName
$name = (Get-AzVirtualNetwork -ResourceGroupName $ResourceGroup | Select Name).Name
Write-Output "{`n`t""name"":""$name""`n}"
When i don't use the .name in the out, this is what I get:
data.external.runpwsh: Refreshing state...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
vnet = { "name" = "" }
And this is the output from the .ps1:
{
"name":"vnettest"
}
Upvotes: 0
Views: 1161
Reputation: 588
Can you check if pwsh is working in the terminal. It should bring up the PowerShell prompt...
The path of pwsh
must be added to the PATH.. /usr/bin
is in my PATH
as you can see here:
ubuntu@myhost:~$ whereis pwsh
pwsh: /usr/bin/pwsh
ubuntu@myhost:~$
ubuntu@myhost:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ubuntu@myhost:~$ pwsh
PowerShell 7.0.3
Copyright (c) Microsoft Corporation. All rights reserved.
https://aka.ms/powershell
Type 'help' to get help.
PS /home/ubuntu>
PS /home/ubuntu> exit
ubuntu@myhost:~$
Added later after 29 Sep 2020.
I tried again in Ubuntu 20.
I tried the below test code which worked.
variable runPSVer6 {}
default = true
}
data "external" "testps" {
program = [var.runPSVer6 == true ? "pwsh" : "powershell","/tmp/testScript.ps1"]
}
output "ps_out" {
value = data.external.testps.result
}
The output was like...
Outputs:
ps_out = {
"name" = "My Resource Name"
"region" = "West Europe"
}
/tmp/testScript.ps1 code was simple output statement...
Write-Output '{ "name" : "My Resource Name", "region" : "West Europe" }'
I tried to null out the path variable just to see if i get the error message you mentioned. I did, as expected..
ubuntu@ip-172-31-53-128:~$ ./terraform apply
data.external.test_ps: Refreshing state...
Error: can't find external program "pwsh"
on main.tf line 5, in data "external" "test_ps":
5: data "external" "test_ps" {
but when i used the full path, it worked again. (even /snap/bin/powershell works)
program = [var.runPSVer6 == true ? "/snap/bin/pwsh" : "powershell","/tmp/testScript.ps1"]
I ealier wrognly blamed snap with my issue, but snap did work now. This does not give any clue here or pin-point the issue you are having. But may be you try a couple of things just to be sure, 1.) issue "pwsh" in the current directory and see that Powershell prompt does come up.. not sure if you already checked this, but sometime some other characters in path could cause an issue. 2.) can you run tf once after exporting PATH=/snap/bin ... (do it inside a shell and exit later so that you back to old path. or. export the correct path later after test) 3.) If you used full path, the error message must have been different other "Error: can't find external program "pwsh" ... can you cross check if there was diff error msg
this is how the pwsh bin and the sym link looks like in my machine...
ubuntu@ip-172-31-53-128:~$ /usr/bin/ls -lt /snap/bin/pwsh
lrwxrwxrwx 1 root root 10 Sep 29 15:40 /snap/bin/pwsh -> powershell
ubuntu@ip-172-31-53-128:~$
ubuntu@ip-172-31-53-128:~$ /usr/bin/ls -lt /snap/bin/powershell
lrwxrwxrwx 1 root root 13 Sep 29 15:40 /snap/bin/powershell -> /usr/bin/snap
ubuntu@ip-172-31-53-128:~$
Upvotes: 1