1

I provisioned VM with following C# snippet

var ssrsVm = new WindowsVirtualMachine("vmssrs001", new WindowsVirtualMachineArgs
{
    Name = "vmssrs001",
    ResourceGroupName = resourceGroup.Name,
    NetworkInterfaceIds = { nic.Id },
    Size = "Standard_B1ms",
    AdminUsername = ssrsLogin,
    AdminPassword = ssrsPassword,
    SourceImageReference = new WindowsVirtualMachineSourceImageReferenceArgs
    {
        Publisher = "microsoftpowerbi",
        Offer = "ssrs-2016",
        Sku = "dev-rs-only",
        Version = "latest"
    },
    OsDisk = new WindowsVirtualMachineOsDiskArgs
    {
        Name = "vmssrs001disk",
        Caching = "ReadWrite",
        DiskSizeGb = 200,
        StorageAccountType = "Standard_LRS",
    }
});

After VM has been provisioned I would like to run a custom Powershell script on it to add a firewall rule. Now wondering how to do this as a part of the Pulumi app. With Azure looks like I could do this with RunPowerShellScript but couldn't find anything about it in Pulumi docs, maybe there is a better way to handle my case?

UPDATE

Thanks to Ash's comment I was able to find VirtualMachineRunCommandByVirtualMachine which seems should do what I'm looking for, but unfortunately, following code snippet returns error

var virtualMachineRunCommandByVirtualMachine = new VirtualMachineRunCommandByVirtualMachine("vmssrs001-script",
    new VirtualMachineRunCommandByVirtualMachineArgs
    {
        ResourceGroupName = resourceGroup.Name,
        VmName = ssrsVm.Name,
        RunAsUser = ssrsLogin,
        RunAsPassword = ssrsPassword,
        RunCommandName = "enable firewall rule for ssrs",
        Source = new VirtualMachineRunCommandScriptSourceArgs
        {
            Script =
                @"Firewall AllowHttpForSSRS
            {
                Name                  = 'AllowHTTPForSSRS'
                DisplayName           = 'AllowHTTPForSSRS'
                Group                 = 'PT Rule Group'
                Ensure                = 'Present'
                Enabled               = 'True'
                Profile               = 'Public'
                Direction             = 'Inbound'
                LocalPort             = ('80')
                Protocol              = 'TCP'
                Description           = 'Firewall Rule for SSRS HTTP'
            }"
        }
    });

error The property 'runCommands' is not valid because the 'Microsoft .Compute/RunCommandPreview' feature is not enabled for this subscription."

Looks like other people are struggling with the same here.

Rob
  • 9,664
  • 3
  • 41
  • 43
  • Could you use a [Compute Extension](https://www.pulumi.com/registry/packages/azure/api-docs/compute/extension/#example-usage) to run your script? More information about the PowerShell side [here](https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-windows#powershell-deployment). – Ash Oct 29 '21 at 10:55
  • @Ash thansk to your answer I also found [VirtualMachineRunCommandByVirtualMachine](https://www.pulumi.com/registry/packages/azure-native/api-docs/compute/virtualmachineruncommandbyvirtualmachine/), will give it a try. – Rob Oct 29 '21 at 11:56
  • `VirtualMachineRunCommandByVirtualMachine` fails with `The property 'runCommands' is not valid because the 'Microsoft .Compute/RunCommandPreview' feature is not enabled for this subscription."` and `Compute Extensions` fails with `VM has reported a failure when processing extension 'vmssrs001-psscript'. Error message: \"Extension '' of Han dler 'Microsoft.Azure.Extensions.CustomScript' version '2.0.7' faulted due to exception during extension processing\"\r\n\r\nMore.. at https://aka.ms/VMExtensionCSELinuxTroubleshoot`. Is `Compute Extensions` available only for Linux based VMs? – Rob Oct 29 '21 at 12:29
  • It isn't Linux only as far as I understand. Do you have this enabled in your subscription `'runCommands' is not valid because the 'Microsoft .Compute/RunCommandPreview' feature is not enabled for this subscription.`. If so, it might be worth logging an issue with Pulimi or clarifying what you're doing on GitHub. – Ash Oct 29 '21 at 12:54
  • 1
    Thanks, Ash, just updated my question and found [this](https://github.com/pulumi/pulumi-azure-native/issues/694) GitHub issue. Can't find `RunCommandPreview` feature on my subscriptions's feature list. Will give another try to your `Compute Extension` idea. – Rob Oct 29 '21 at 12:56
  • 1
    @Ash happy to accept your answer if you will provide one, thanks for your help. – Rob Nov 01 '21 at 13:03

2 Answers2

1

You can use a Compute Extension to execute a script against a VM with Pulumi.

This article details some of the options if you just completed the procedure via PowerShell.

Ash
  • 3,030
  • 3
  • 15
  • 33
1

As an addition to Ash answer here is how I integrated it with Pulumi

  • first, I create a blob container for my project scripts

enter image description here

var deploymentContainer = new BlobContainer("deploymentscripts", new BlobContainerArgs
{
    ContainerName = "deploymentscripts",
    ResourceGroupName = resourceGroup.Name,
    AccountName = storageAccount.Name,
});
  • next, I upload all of my Powershell scripts to create blob

with this snippet

foreach (var file in Directory.EnumerateFiles(Path.Combine(Environment.CurrentDirectory, "Scripts")))
{
    var fileName = Path.GetFileName(file);
    var blob = new Blob(fileName, new BlobArgs
    {
        ResourceGroupName = resourceGroup.Name,
        AccountName = storageAccount.Name,
        ContainerName = deploymentContainer.Name,
        Source = new FileAsset(file),
    });
    
    deploymentFiles[fileName] = SignedBlobReadUrl(blob, deploymentContainer, storageAccount, resourceGroup);
}

SignedBlobReadUrl grabbed from Pulumi repo.

private static Output<string> SignedBlobReadUrl(Blob blob, BlobContainer container, StorageAccount account, ResourceGroup resourceGroup)
{
    return Output.Tuple<string, string, string, string>(
        blob.Name, container.Name, account.Name, resourceGroup.Name).Apply(t =>
    {
        (string blobName, string containerName, string accountName, string resourceGroupName) = t;

        var blobSAS = ListStorageAccountServiceSAS.InvokeAsync(new ListStorageAccountServiceSASArgs
        {
            AccountName = accountName,
            Protocols = HttpProtocol.Https,
            SharedAccessStartTime = "2021-01-01",
            SharedAccessExpiryTime = "2030-01-01",
            Resource = SignedResource.C,
            ResourceGroupName = resourceGroupName,
            Permissions = Permissions.R,
            CanonicalizedResource = "/blob/" + accountName + "/" + containerName,
            CacheControl = "max-age=5",
        });
        return Output.Format($"https://{accountName}.blob.core.windows.net/{containerName}/{blobName}?{blobSAS.Result.ServiceSasToken}");
    });
}
  • and lastly, I create Extension to run my script

code

var extension = new Extension("ssrsvmscript", new Pulumi.Azure.Compute.ExtensionArgs
{
    Name = "ssrsvmscript",
    VirtualMachineId = ssrsVm.Id,
    Publisher = "Microsoft.Compute",
    Type = "CustomScriptExtension",
    TypeHandlerVersion = "1.10",
    Settings = deploymentFiles["ssrsvm.ps1"].Apply(script => @" {
    ""commandToExecute"": ""powershell -ExecutionPolicy Unrestricted -File ssrsvm.ps1"",
    ""fileUris"": [" + "\"" + script + "\"" + "]}")
});

Hope that will save some time someone else struggling with the problem.

Rob
  • 9,664
  • 3
  • 41
  • 43