"Future#WaitForCompletion" while running a powershell script from GitHub - Terraform - azure

I have a powershell script present in GitHub and using it in the "Settings" block inside "azurerm_virtual_machine_extension" to configure the Windows Server VM. Below is the code.
resource "azurerm_virtual_machine_extension" "iis-windows-vm" {
depends_on = [azurerm_windows_virtual_machine.web-windows-vm]
name = "win-${random_string.random-win-vm.result}-vm-extn"
virtual_machine_id = azurerm_windows_virtual_machine.web-windows-vm.id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.9"
settings = <<SETTINGS
{
"commandToExecute": "powershell -ExecutionPolicy Unrestricted -File demo.ps1",
"fileUris": ["https://raw.githubusercontent.com/Configure/app/master/demo.ps1"]
}
SETTINGS
}
And the below are the content of "demo.ps1"
New-LocalUser "ansible" -Password (ConvertTo-SecureString -AsPlainText -Force ) -AccountNeverExpires:$true -PasswordNeverExpires:$true -FullName "ansible" | Add-LocalGroupMember -Group administrators
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file
Install-WindowsFeature -Name Web-Server -IncludeAllSubFeature -IncludeManagementTools
When I do "terraform apply", below error is displayed.
Error: Future#WaitForCompletion: context has been cancelled: StatusCode=200 -- Original Error: context deadline exceeded
The code was working fine until now. Not able to figure out the problem here. Request you assist me to make this work.

The error Original Error: context deadline exceeded means that we ran into a situation where a given action was not completed in an expected timeframe.
So there can be a handful of reason why you are encountering the execution timeout like Network Latency, Slow I/O, Firewall Rules and many more. One possible reason that I think is the URL is not responding as expected or it's taking to much time to respond.
Before being able to solve the problem, you need to determine what is actually failing. I would suggest to check the detailed terraform log file to find the reason of timeout.
But even after checking you find is good and you are still facing the issue then with v2.0 of the AzureRM Provider it is possible to add custom timeouts using timeouts block as shown in the example snippet below.
resource "azurerm_resource_group" "example" {
name = "example-resource-group"
location = "West Europe"
timeouts {
create = "10m"
delete = "30m"
}
}
For more information check this Custom Timeouts for Resources section of the terraform document.

Related

Provisioning Script using CustomScriptExtension on Windows2019 Fails

I'm trying to wrap my brain around an issue with either the TF Code, or me. I've got a VM Set that I'm mapping over, and on each one, I have a CustomScriptExtension that should install Docker on the VMs.
When I run the plan, it builds the VMs, and the Custom Script runs, however when I RDP into the machine, and attempt a docker info It's telling me that docker isn't installed.
A quick cursory glance of C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.*\Downloads\ Shows that the installer script is indeed being downloaded, but it doesn't seem to be installing.
Here's the AzureRM Resource (Sanitized):
resource "azurerm_virtual_machine_extension" "bootstrap-scripts" {
for_each = local.XXXXXX
name = "${each.key}-bootstrap"
virtual_machine_id = module.XXXXXXXX[each.key].virtual_machine_id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"
settings = <<SETTINGS
{
"commandToExecute" : "powershell -ExecutionPolicy Unrestricted -File install-docker-ce.ps1",
"fileUris" : ["https://raw.githubusercontent.com/microsoft/Windows-Containers/Main/helpful_tools/Install-DockerCE/install-docker-ce.ps1"]
}
SETTINGS
}
And the output from the log at C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension
[
{
"version":"1",
"timestampUTC":"2022-10-21T20:03:44.6989395Z",
"status":{"name":"powershell -ExecutionPolicy Unrestricted -File install-docker-ce.ps1",
"operation":"Command Execution Finished",
"status":"success",
"code":0,
"formattedMessage":{
"lang":"en-US",
"message":"Command execution finished"
},
"substatus":[
{
"name":"StdOut",
"status":"success",
"code":0,"formattedMessage":{
"lang":"en-US",
"message":"Querying status of Windows feature: Containers...\r\nEnabling feature Containers...\r\nWARNING: You must restart this server to finish the installation process.\r\nRestart is required; restarting now...\r\nCreating scheduled task action (C:\\Packages\\Plugins\\Microsoft.Compute.CustomScriptExtension\\1.10.12\\Downloads\\0\\install-docker-ce.ps1 )...\r\nCreating scheduled task trigger...\r\nRegistering script to re-run at next user logon...\r\n"
}
},
{
"name":"StdErr",
"status":"success",
"code":0,
"formattedMessage":{
"lang":"en-US",
"message":"Register-ScheduledTask : No mapping between account names and security IDs was done.\r\n(12,8):UserId:\r\nAt C:\\Packages\\Plugins\\Microsoft.Compute.CustomScriptExtension\\1.10.12\\Downloads\\0\\install-docker-ce.ps1:150 char:5\r\n+ Register-ScheduledTask -TaskName $global:BootstrapTask -Action $a ...\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : NotSpecified: (PS_ScheduledTask:Root/Microsoft/...S_ScheduledTask) [Register-ScheduledTa \r\n sk], CimException\r\n + FullyQualifiedErrorId : HRESULT 0x80070534,Register-ScheduledTask\r\n \r\n"
}
}
]
}
}
]
from what I'm reading, it seems to set up the scheduled task to reboot the server, but it looks like it never does? However even after a manual restart, it's still not installed.
Can anyone shed some light on this?
EDIT: I forgot to mention that I cannot use anything out of the Azure Public Marketplace, in case someone wanted to mention using a premade image. I am relegated to using images that are stored in our private collection

PowerShell Task not running the script in Azure Pipelines?

I have a powershell task that is used to run a script which involves creating azure resources (Example: Resource group, Azure Key Vault, Function App...). When the pipeline is being run and it arrives to the powershell task in the deploy stage, it shows the following message:
The problem here, it says Finishing:Powershell but it didn't execute the script and did not create any azure resource.
Here is a sample of the powershell script:
$vaultName = "key vault name"
$blobstorageName = "blob storage name"
$Location = "Location Name"
$resourceGroupName = "Resource Group Name"
try {
#Creation of Resource Group
$resourceGroup = Get-AzResourceGroup -ResourceGroupName $resourceGroupName -ErrorAction SilentlyContinue
if($null -eq $resourceGroup)
{
New-AzResourceGroup -Name $resourceGroupName -Location $Location
}
else
{
Write-Host "The ResourceGroup with the name: $resourceGroupName already exists."
}
# Creation of Storage Account
$checkBlobStorage = (Get-AzStorageAccountNameAvailability -Name $blobstorageName) | Select-Object NameAvailable
if ($checkBlobStorage.NameAvailable)
{
New-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $blobstorageName -Location $Location -SkuName Standard_LRS -Kind StorageV2 -AccessTier Hot
}
else
{
Write-Host "The name $blobStorageName is not available. Suggest a new globally unique name!"
}
catch
{
}
Does anyone have a clue what is wrong ? Am I missing something in the powershell script (Maybe I don't have direct access to the azure portal from azure devops) or maybe something is missing in
the Yaml file ?
Two major issues:
you seem to be using the Powershell Task, which is not designed for communication with Azure. You should use the Azure Powershell task for this kind of script, because it already has the right modules loaded and the authentication prepared.
your script is swallowing the error so it is hiding what went wrong. It's usually more useful not to catch exceptions; if your script is erroring then let it error, and let the pipeline show you in its log what has happened.

Not Able to add a custom script extension for Linux vm

I have a linux Cent OS vm and am trying to add a custom script to it. If i do it manually from the portal i am able to install the custom script extension for linux. But i am not able to install the custom script via powershell code that i added below. Need some help on it. I am storing the custom script file in a storage account and calling it from there when installing the custom script extension on Linux.
Error i get is : Enable failed: processing file downloads failed: failed to download file[0]: failed to download file: unexpected status code: actual=404 expected=200
if($vmname.OSType -eq "Linux"){
$resourcegroup=$vmname.ResourceGroupName
$location=$vmname.Location
$vm=$vmname.Name
$TheURI = "https://storageaccount.blob.core.windows.net/container/cstmscript.sh"
$ScriptSettings = #{"fileUris" = #($TheURI); "commandToExecute" = "sh cstmscript.sh";}
Set-AzVMExtension -ResourceGroupName $resourcegroup -VMName $vm -Name "Custom Script" -Publisher "Microsoft.Azure.Extensions" -TypeHandlerVersion 2.0 -ExtensionType "CustomScript" -Location $location -Settings $ScriptSettings
}
Cant use Set-AzVMCustomScriptExtension as that's for only Windows VM's
Thanks Satya It did work Btw . I needed to add the access keys.
here is the code
if($vmname.OSType -eq "Linux"){
$resourcegroup=$vmname.ResourceGroupName
$location=$vmname.Location
$vm=$vmname.Name
$TheURI = "https://storage.blob.core.windows.net/container/cstmscript.sh"
$ScriptSettings = #{"fileUris" = #($TheURI); "commandToExecute" = " sh cstmscript.sh";}
$ProtectedSettings = #{"storageAccountName"="storage";"storageAccountKey" = ""};
Set-AzVMExtension -ResourceGroupName $resourcegroup -VMName $vm -Name "Custom Script" -Publisher "Microsoft.Azure.Extensions" -TypeHandlerVersion 2.0 -ExtensionType "CustomScript" -Location $location -Settings $ScriptSettings -ProtectedSettings $ProtectedSettings
}
I had tried hitting the above the url
https://storageaccount.blob.core.windows.net/container/cstmscript.sh
Which is more or less 404 error as encountered below :
Enable failed: processing file downloads failed: failed to download file[0]: failed to download file: unexpected status code: actual=404 expected=200
Looks like you re not able to access the cstmsscript.sh & encountering a 404 - you will have to host the file anonymously accessible or alternatively use means to grant access ( like SAS )

Create Azure Objects Using 'Publish Settings' File

So, I'm told if you import your Azure Subscription Publish Setting file into PowerShell...you can use the certificate in the Publish Setting file to create objects in your Azure Subscription.
However, I am getting the following exception trying to create a Resource Group:
New-AzureRmResourceGroup : Run Connect-AzureRmAccount to login.
+ CategoryInfo : CloseError: (:) [New-AzureRmResourceGroup], PSInvalidOperationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.NewAzureResourceGroupCmdlet
I Do The Following In My Script:
"Import" the Subscription
"Select" the Subscription
"Get" the Subscription (to view it)
...the subscription is both "Default & Current" (see attached image).
...and yet I still get that message.
SAMPLE CODE:
This code is edited so as not to "give away the farm"...
#Set Subscription
$Subscription_Id = "<not shown>"
Select-AzureSubscription -SubscriptionId $Subscription_Id
Get-AzureSubscription
# CHECK EXISTS: ResourceGroup
$RegionFullName = "South Central US"
$RegionShortName = "scus"
$EnvironmentShortName = "dev"
$ApplicationShortName = "<not shown>"
$ObjectTypeShortName = "rg"
$ResourceGroupFullName = "$($RegionShortName)-$($EnvironmentShortName)-$($ApplicationShortName)-$($ObjectTypeShortName)"
$ResourceGroup = Get-AzureRmResourceGroup -Name $ResourceGroupFullName -ErrorVariable NotPresent -ErrorAction SilentlyContinue
if ($ResourceGroup -eq $Null) {
#CREATE: ResourceGroup
$ResourceGroup = New-AzureRmResourceGroup -Name $ResourceGroupFullName -Location $RegionFullName -Confirm
}
I suppose you are using Import-PublishSettingsFile, but Azure Management Certificates and Publishing Setting files are only intended (for) and (are) limited to managing Azure Service Management (ASM) resources, which are being retired.
In your script, you mixed the ASM and AzureRm powershell modules together. Select-AzureSubscription and Get-AzureSubscription belong to ASM, Get-AzureRmResourceGroup and New-AzureRmResourceGroup belong to AzureRm.
So if you need to use AzureRm command, you need to run Connect-AzureRmAccount to login your account.

Running Powershell script in Terraform module

Am currently running some Terraform to create resources in Azure. We have a module we have written to create a resource group with a bunch of variables. The provider currently does not allow the creation of budgets and cost alerts but the Powershell modules do. I thought we could then add a Powershell script to carry out the settings. I seem to be hitting a snag where I cannot quite work out how to address the Powershell script. I have the following:
resource "null_resource" "PowerShellScriptRunAlways" {
triggers = {
always_run = "${timestamp()}"
}
provisioner "local-exec" {
command = ".'${path.module}//pwsh//costalert.ps1 -subscriptionID \"${var.azure_subscription_id}\" -tenantID \"${var.azure_tenant_id}\" -clientID \"${var.azure_client_id}\" -clientSecret \"${var.azure_client_secret}\" -budgetAmount \"${var.budgetAmount}\" -rgName \"${azurerm_resource_group.this.name}\" -emailAddresses \"${var.emailAddresses}\"'"
interpreter = ["pwsh", "-Command"]
}
}
using pwsh as this is running on a Linux Jenkins agent. This is part of a module where the ps1 file is under "root module directory/pwsh" but it seems to yield the following:
Error: Error running command '.'.terraform/modules/rg_test\pwsh\costalert.ps1 -subscriptionID "xxxxx" -tenantID "xxxxxxx" -clientID "xxxxxx" -clientSecret "xxxxx" -budgetAmount "1000" -rgName "rg-da_test-sbxeng-001" -emailAddresses "xxxxxx"'': exit status 1. Output: . : The module '.terraform/modules/rg_test' could not be loaded. For more information, run 'Import-Module .terraform/modules/rg_test
+ .'.terraform/modules/rg_test\pwsh\costalert.ps1 -subscriptionID
It seems to be switching the path but cannot seem to make it pick up the script and run it. Does anyone have any suggestions?
Isn't this a quoting issue?
I can successfully execute this pwsh null resource from a terraform module in an Azure DevOps linux agent. Note that only the script path is single quoted, while in your example you've got the whole command single quoted.
resource "null_resource" "create_sql_user" {
provisioner "local-exec" {
command = ".'${path.module}\\scripts\\create-sql-user.ps1' -password \"${random_password.sql_password.result}\" -username \"${var.sql_username}\" -sqlSaConnectionString \"${var.sql_server_connectionstring}\" -databaseName \"${azurerm_sql_database.db.name}\" "
interpreter = ["pwsh", "-Command"]
}
depends_on = [azurerm_sql_database.db]
}

Resources