Google Cloud Compute Engine API: createVM directly with setMetadata - node.js

I use #google-cloud/compute to create VM instances automatically.
Also I use startup scripts in those instances.
So, firstly I call Zone.createVM and then VM.setMetadata.
But in some regions startup script is not running. And it is running after VM reset, so looks like my VM.setMetadata call is just too late.
In the web-interface we can create VM directly with metadata. But I do not see this ability in API.
Can it be done with API?

To set up a startup script during instance deployment you can provide it as part of the metadata property in the API call:
POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances
{
...
"metadata": {
"items": [
{
"key": "startup-script",
"value": "#! /bin/bash\n\n# Installs apache and a custom homepage\napt-get update\napt-get install -y apache2\ncat <<EOF > /var/www/html/index.html\n<html><body><h1>Hello World</h1>\n<p>This page was created from a simple start up script!</p>\n</body></html>"
}
]
}
...
}
See the full reference for the resource "compute.instances" of the Compute Engine API here.
Basically, if you are using a Nodejs library to create the instance you are already calling this, so you will only need to add the metadata keys as documented.
Also, if you are doing this frequently I guess it would be more practical if you stored the script in a bucket in GCP and simply add the URI to the metadata like this:
"metadata": {
"items": [
{
"key": "startup-script-url",
"value": "gs://bucket/myfile"
}
]
},

Related

Can you include scripts to be run as azure functions in a managed app .zip file?

I want to include some functionality via an azure function along with my managed app and was hoping I could include it in the .zip file you specify which has your mainTemplate.json and createUiDefinition.json files in it.
If so, where do you put them, and then how are they configured to run? What identity do they run as, what is their URL, etc? Can they just be "consumption" model (i.e. CPU allocated as needed instead of a dedicated server pool)? These are all low-frequency, high-latency type operations I want to provide.
I've found documentation that says you can put additional resources in the .zip file but nowhere that talks about actually doing it or how to use them.
Of if I'm totally off base, how does one provide specific behaviors along with a managed app to a customer? I'd really rather not host the functions myself, but if that's how you have to do it...
Thank you.
This guide here has a section on deployment artifacts, which includes the information you need:
https://github.com/Azure/azure-quickstart-templates/blob/master/1-CONTRIBUTION-GUIDE/best-practices.md
To summarise that page, you can include your scripts anywhere in the zip, but best practice is to not have it at the top level.
To get the URI in the main template, you need to add the following parameters:
"parameters": {
"_artifactsLocation": {
"type": "string",
"metadata": {
"description": "The base URI where artifacts required by this template are located including a trailing '/'"
},
"defaultValue": "[deployment().properties.templateLink.uri]"
},
"_artifactsLocationSasToken": {
"type": "securestring",
"metadata": {
"description": "The sasToken required to access _artifactsLocation if needed."
},
"defaultValue": ""
}
},
Then get the full path to your resource using the URI function, like in this example:
"variables": {
"scriptFileUri": "[uri(parameters('_artifactsLocation'), concat('scripts/configuration.sh', parameters('_artifactsLocationSasToken')))]",
"nestedtemplateUri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/jumpbox.json', parameters('_artifactsLocationSasToken')))]"
},

Deploy Azure Function dynamically enabled/disabled using ARM template

I have a class library, timer-based Azure Function that is deployed using an ARM template. Everything works fine except I would like a slightly different behavior based on the target environment. When deploying to a test environment I would like the function to be initially disabled but in production it should always be enabled. Is this possible?
My current workaround is to have an app setting that tells the function to immediately exit when set to a specific value. However, this seems like a poor solution, especially since the timer-triggered function is executed quite frequently. To solve this I manually disables the function using the following switch in the Azure portal:
Is there perhaps possible to specify the desired state of this switch from the ARM template?
Seems you don't need to set to a specific value in the app settings, azure function has a built-in property.
Try to use the setting in the template snippet below to disable the function, it should work.
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobs.MessageQueueMonitorFunction.Disabled",
"value": "true"
}
]
}
Expanding on Joy's answer, which worked like a charm!
For the benefit of others, the "name" property above is composed like so:
AzureWebJobs.<YouFunctionName>.Disabled
where <YouFunctionName> is specified in your template.json here:
{
"resources": [
"name": "<YourFunctionName>",
"type": "functions",
"properties": {
"config": {
"bindings": [
{
...
}
]
}
}
]
}

set Environment variable for OPC publisher

i have an OPC-publisher module which i want to deploy as an iot edge module for this purpose i need to give connectionString. in the documentation given on github they have mentioned some environment variables which can be set for this purpose as follows:
There are a couple of environment variables which can be used to control the application:
_HUB_CS: sets the IoTHub owner connectionstring
_GW_LOGP: sets the filename of the log file to use
_TPC_SP: sets the path to store certificates of trusted stations
_GW_PNFP: sets the filename of the publishing configuration file
i want to know where to set them in a code, on azure portal where they provide an option for setting env variables, from command line, or in dockerfile.
any help will be appriciated.
Did you take a look at this? It explains in detail how to run the OPC publisher as an Edge module. Just copying here for completeness:
{
"Hostname": "pub-test",
"Cmd": [
"publisher",
"--pf=./pn.json",
"--di=60",
"--to",
"--aa",
"--si=0",
"--ms=0"
],
"HostConfig": {
"PortBindings": {
"62222/tcp": [{
"HostPort": "62222"
}]
},
"Binds": [
"x509certstores:/root/.dotnet/corefx/cryptography/x509stores",
"d:/iiotedge:/appdata"
],
"ExtraHosts": [
"localhost:127.0.0.1",
"opctestsvr:192.168.178.26"
]
}
}

Run multiple custom scripts through Azure templates on same VM

I have python script1.py and bash script script2.sh to run after VM is created through ARM template using below snippet. For some reason when I add this script2.sh VM creation fails. 'fileUris' as well as commandToExecute are correct. What could be the reason , and where to look for errors ?
{
"name": "[concat(variables('web'),'/script1')]",
"properties":
{
"settings": {
"fileUris": ["https://.../script1.py"],
"commandToExecute": "python script1.py"
}
}
},
{
"name": "[concat(variables('web'),'/script2')]",
"properties":
{
"settings": {
"fileUris": ["https://.../script2.sh"],
"commandToExecute": "bash script2.sh"
}
}
},
I ommit type, apiVersion, location as well as publisher, type and typeHandlerVersion for clarity. Both scripts depend on "[concat('Microsoft.Compute/virtualMachines/', variables('web'))]"
For Azure VM extension, it's an Azure resource, not the property of a resource. So if you want to add the multi extensions to the VM in one template, you should make each extension as one resource. Here is the example.
update
And if there are two or more extensions in one template, you should make sure the order of the extensions to execute. Although multi extensions in one template, they are still executing one by one in the VM.
For example, the first extension named
"[concat(variables('vmName'),'/', 'antiMalwareExtension')]"
and you need to add "dependsOn" in the second extension:
"dependsOn":[
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]",
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'),'/', 'antiMalwareExtension')]"
],
The extensions after also should do like this.

Issues deploying dscExtension to Azure VMSS

I've been having some issues deploying a dscExtension to an Azure virtual machine scale set (VMSS) using a deployment template.
Here's how I've added it to my template:
{
"name": "dscExtension",
"properties": {
"publisher": "Microsoft.Powershell",
"type": "DSC",
"typeHandlerVersion": "2.9",
"autoUpgradeMinorVersion": true,
"settings": {
"ModulesUrl": "[concat(parameters('_artifactsLocation'), '/', 'MyDscPackage.zip', parameters('_artifactsLocationSasToken'))]",
"ConfigurationFunction": "CmvmProcessor.ps1\\CmvmProcessor",
"Properties": [
{
"Name": "ServiceCredentials",
"Value": {
"UserName": "parameters('administratorLogin')",
"Password": "parameters('administratorLoginPassword')"
},
"TypeName": "System.Management.Automation.PSCredential"
}
]
}
}
}
The VMSS itself is successfully deploying, but when I browse the InstanceView of the individual VMs, the dscExtension shows the failed status with an error message.
The problems I'm having are as follows:
The ARM deployment does not try to update the dscExtension upon redeploy. I am used to MSDeploy web app extensions where the artifacts are updated and the code is redeployed on each new deployment. I do not know how to force it to update the dscExtension with new binaries. In fact it only seems to give an error on the first deploy of the VMSS, then it won't even try again.
The error I'm getting is for old code that doesn't exist anymore.
I had a bug previously in a custom DSC Powershell script where I tried to use the -replace operator which is supposed to create a $Matches variable but it was saying $Matches didn't exist.
In any case, I've since refactored the code and deleted the entire resource group then redeployed. The dscExtension is still giving the same error. I've verified the blob storage account where my DSC .zip is located no longer has the code which is capable of producing this error message. Azure must be caching the dscExtension somewhere. I can't get it to use my new blob .zip that I upload before each deployment.
Any insight into the DSC Extension and how to force it to update on deploy?
It sounds like you may be running into multiple things here, so trying the simple one first. In order to get a VM extension to run on a subsequent deployment you have to "seed" it. (and you're right this is different than the rest of AzureRM) Take a look at this template:
https://github.com/bmoore-msft/AzureRM-Samples/blob/master/VMDSCInstallFile/azuredeploy.json
There is a property on the DSC extension called:
"forceUpdateTag" : "changeThisToEnsureScriptRuns-maxlength=50",
The property value must be different if you ever want the extension to run again. So for example, if you wanted it to run every time you'd seed it with a random number or a guid. You could also use version numbers if you wanted to version it somehow. The point is, if the value in the template is the same as the one you're passing in, the extension won't run again.
That sample uses a VM, but the VMSS syntax should be the same. That property also applies to other extensions (e.g. custom script).
The part that seems odd is that you said you deleted the entire RG and couldn't get it to accept the new package... That sounds bad (i.e. like a bug). If the above doesn't fix it, we may need to dig deeper into the template and script. LMK...

Resources