How to reference virtual machine name of VMSS in JSON template - json

Is there a way to reference a VM name that is deployed in VM Scale Set? I'm using custom script extension that runs install script when each VM in scale set is deployed and for one of the parameters of the script I want to use a name of the VM. For single instance it was easy:
"commandToExecute": "[concat('sh ap-cluster-setup.sh -h=',parameters('virtualMachineName'),' -s=',parameters('subnetAddressPrefix'),'')]"
but since VM name in scale set is created dynamically when it is deployed I can't think of a way to reference it in JSON. The VM naming convention is vmssTemplate_0, vmssTemplate_1, etc. where vmssTemplate is parameters('virtualMachineScaleSets_name') in VMSS template.

There's no way to do this in the template itself since the same parameters get passed to each VM on script execution. However, You should be able to figure out the VM name from within the script. For instance, on a Linux machine you could use the hostname command, which will return the VM name. Does this meet your needs?

where vmssTemplate is parameters('virtualMachineScaleSets_name') in
VMSS template.
We can find where vmss template define the Virtual machine's name.
computernameprefix:
"osProfile": {
"computerNamePrefix": "[variables('namingInfix')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
and the 'namingInfix' define here:
"namingInfix": "[toLower(substring(concat(parameters('vmssName'), uniqueString(resourceGroup().id)), 1, 9))]",
By default the VMSS with autoscale settings, and the vm's name should be create automatically.
If you want to get the VMs' name, we can use powershell to get it:
PS C:\windows> Get-AzureRmVmssVM -ResourceGroupName YOUR_RESOURCE_NAME -VMScaleSetName YOUR_VMSS_NAME
Also you can add some script (to get the name of your VMs) in your script, then upload the script to custom script extension.

Related

Python code in Google Cloud function not showing desired output

I have the following lines of python code
import os
def hello_world():
r=os.system("curl ipinfo.io/ip")
print (r)
hello_world()
Shows the desired output when executed from command line in Google Cloud Shell but seems there is a 0 at the end of IP Address output
$ python3 main2.py
34.X.X.2490
When I deployed the same code in Google CLoud function it is showing OK as output
I have to replace the first line of code in GCF as follows to make it deploy.
def hello_world(self):
Any suggestion so that GCF displays the desired output which is the output of curl command?
Your function won't work for 2 reasons:
Firstly, you don't respect the HTTP Cloud Function Python function signature:
def hello_world(request):
....
Secondly, you can't use system call. In fact not exactly, you can perform system call, but, because you don't know which package/binaries are installed, you can't rely on this. It's serverless, you don't manage the underlying infrastructure and runtime environment.
Here you made the assumption that CURL is installed on the runtime image. Maybe yes, maybe not, maybe it was, maybe it will be remove in future!! You can't rely on that!!
If you want to manage you runtime environment, you can use Cloud Run. You will manage your runtime environment, and you can install what you want on it and then you are sure of what you can do.
Last remarks:
note: instead of performing a CURL, you can perform a http get request to the same URL to get the IP
Why do you want to know the outgoing IP? It's serverless, you also don't manage the network. You will reach the internet through a Google IPs. It can change everytime, and other cloud functions (or cloud run), from your projects or project from others (like me), are able to use the same IPs. It's Google IPs, not yours! If it's your requirement, let me know, there are solutions for that!

ARM template to create a VM using an existing VNet and subnet

recently I started learning/working with ARM templates and JSON so I'm a complete newbie to this. I've been asked to make a template that creates a virtual machine selecting an existing virtual network and subnet within a subscription.
Everything works fine, except that whenever I make the deployment, the template creates a new vnet and subnet with randomized names instead of letting me pick from an existing one (the VM creates correctly though).
I used https://github.com/Azure/azure-quickstart-templates/blob/master/101-vm-simple-rhel/azuredeploy.json quickstart template as a base and added a few lines (which I will put below) to let me type the name of my vnet and subnet as it does with the VM name, but it keeps creating new ones even though I type the name correctly.
The lines I added to the code in the Parameters section are:
"virtualNetworkName": {
"type": "string",
"metadata": {
"description": "VNet to which the VM will connect."
}
},
"subnetName": {
"type": "string",
"metadata": {
"description": "Subnet to which the VM will connect."
}
}
Thank you in advance for your time!
To create a VM with the existing VNet base on the quickstart template you used, you only need to delete the virtual network resource in the resources block and the dependency on it and all the variables about the VNet and subnet except the variable subnetRef, then change this variable with your parameters like this if the VNet in the same resource group with the VM:
"subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]",
If the existing VNet in another resource group but in the same subscription, then the variable subnetRef should be changed like this:
"subnetRef": "[resourceId('otherResourceGroup', 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]",
According to the changes, the template will use the existing VNet and subnet instead of creating new ones.
Take a look at this sample:
https://github.com/Azure/azure-quickstart-templates/tree/master/100-marketplace-sample
It shows how you can use a pattern for new/existing/none on resources in a template.

Azure Devops Packer Build Agent (Define Vnet IP Range for the temporary Resource group which packer creates to take snapshot))

I am trying to build a packer image on azure. How do i Define Vnet and VM IP Ranges for Temporary packer Resource group(Which packer temporarily creates and destroys(Vnet,vm))to take a snapshot of the vm? I wanted to make sure that the default IP's Used by packer will not overlap with my exisiting IP's in the azure subscription
You can specify the options inside of your packer template to use an existing resource group and virtual network. See example below
{
"builders": [{
"type": "azure-arm",
"client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
"client_secret": "ppppppp-pppp-pppp-pppp-ppppppppppp",
"tenant_id": "zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
"subscription_id": "yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyy",
// These will allow you to select existing resources
"build_resource_group_name": "my-existing-rg" // name of existing resource group
"virtual_network_name": "my-existing-vnet" // name of existing vnet
"virtual_network_subnet_name": "mySubnetName" // name of subnet inside vnet
"private_virtual_network_with_public_ip": true // apply public IP to VM (optional)
// Continue with rest of configuration
}
See https://www.packer.io/docs/builders/azure.html for reference

How to use --attach-data-disks when creating new VM using Azure CLI2?

I'm trying to create a new VM using existing Managed disks and I keep running into problems because the parameters are not very well documented.
One problem that I haven't figured out is the format of --attach-data-disks
From the name and description of the parameter this seems to be the way you can attach data disks to the VM that you are creating and I am assuming because it is --attach-data-disks and not --attach-data-disk that you can attach multiple disks using this parameter.
What I don't know is what format to use when passing multiple disks. I have tried separating them using commas but the error that I got seemed to indicate that it viewed the comma delimited list of drives as one long name for a drive.
Here is an example of what I am trying to do:
az vm create -g test-group -n testvm2 --os-type windows --attach-os-disk testvm1-osdisk-20181213-033052 --attach-data-disks "testvm1-datadisk-000-20181213-033052,testvm1-datadisk-001-20181213-033052,testvm1-datadisk-002-20181213-033052"
Error I'm getting:
Deployment failed. Correlation ID: 9999. {
"error": {
"code": "InvalidParameter",
"message": "Id /subscriptions/99999999/resourceGroups/lbacompensafe/providers/Microsoft.Compute/disks/testvm1-datadisk-000-20181213-033052,testvm1-datadisk-001-20181213-033052,testvm1-datadisk-002-20181213-033052 is not a valid resource reference.",
"target": "dataDisk.managedDisk.id"
}
}
I'm running the commands from Powershell, not Bash, if that makes a difference.
Figured it out. It is in fact a space delimited list. I didn't try this sooner because I incorrectly assumeed it would need some sort of grouping or it would look like different parameters, but just listing them out like
--attach-data-disks disk1 disk2 disk3
Will add them in that order. Wish the docs would have just said so. Would have saved me a bunch of time.

Getting external IP of created google instance for a particular interface using terraform

I am using terraform to create and configure my GCE instance. I have configured 4 interfaces on the GCE interface, Now i want the external IP of the managenment interface using terraform for this instance .
For aws , we have some concept of
output "ip" {
value = "${aws_eip.ip.public_ip}"
}
so i was wondering if i could use GCE equivalent for this . In short I want to store the external IP of the created instance on my local instance preferably in a variable
I used output variable to get IP computed during instance creation
output "mgt0ip" {
value = "${google_compute_instance.default.network_interface.0.access_config.0.nat_ip}"
}