How to deploy or delete several virtual machines at once with Azure PowerShell? - azure-virtual-machine

How can I do multiple operations on multiple VM's like creating or deleting 10 VM's through Azure PowerShell scripts?

Generally, we deploy a bunch of VMs in order to increase the availability and reliability of Virtual Machine solutions on Azure using Availability Sets or manage a set of identical, auto-scaling virtual machines using virtual machine scale sets.
In this case, if you just want to deploy a volume of VMs once time. You can use a for loop with powershell. For example, you create two VMs as following steps:
Create a resource group
New-AzureRmResourceGroup -ResourceGroupName "ResourceGroupVM" -Location "EastUS"
Create 2 VMs using FOR loop.
for ($i=1; $i -le 2; $i++)
{
$cred = Get-Credential
New-AzureRmVm `
-ResourceGroupName "ResourceGroupVM" `
-Name "myVM$i" `
-Location "East US" `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-SecurityGroupName "myNetworkSecurityGroup" `
-PublicIpAddressName "myPublicIpAddress$i" `
-Credential $cred
}
Remove your resource group to remove VMs.
Remove-AzureRmResourceGroup -Name "ResourceGroupVM" -Force
However, it is recommended to use the template to deploy many independent VMs. You can create a template file that deploys the resources and a parameters file that supplies parameter values to the template. Then deploy the template. Using template is a more flexible method to deploy many personalized VMs that you can specific lots of properties (e.g. virtual network, subnet, load balancer configs, etc.)

Related

Using multiple SSH keys for different hosts with Ansible EC2 Inventory Plugin

I am trying to use Ansible to install applications across a number of existing AWS EC2 instances which use a number of different SSH keys and usernames on different Linux OSes. Because of the changing state of the existing instances I am attempting to use Ansible's Dynamic Inventory via the aws_ec2 inventory plugin as recommended.
I am able to group the hosts by key_name but now need to run the Ansible playbook against this inventory using the relevant SSH key and username according to the group, structured as the below example output from ansible-inventory -i inventory.aws_ec2.yml --graph:
#all:
|--#_SSHkey1:
| |--hostnameA
| |--hostnameB
|--#_SSHkey2:
| |--hostnameC
|--#_SSHkey3:
| |--hostnameD
| |--hostnameE
| |--hostnameF
|--#aws_ec2:
| |--hostnameA
| |--hostnameB
| |--hostnameC
| |--hostnameD
| |--hostnameE
| |--hostnameF
|--#ungrouped:
I have tried creating a separate hosts file (as per the below) using the groups as listed above, providing the path to the relevant SSH key but I am unsure how you would use this with the dynamic inventory.
[SSHkey1]
ansible_user=ec2-user
ansible_ssh_private_key_file=/path/to/SSHkey1
[SSHkey2]
ansible_user=ubuntu
ansible_ssh_private_key_file=/path/to/SSHkey2
[SSHkey3]
ansible_user=ec2-user
ansible_ssh_private_key_file=/path/to/SSHkey3
This is not explained in the official Ansible documentation here and here but should be a common use case. A lot of the documentation I have found refers to an older method of using Dynamic Inventory using a python script (ec2.py) which is deprecated and so is no longer relevant (for instance this AWS post).
I have found a similar unanswered question here (Part 3).
Any links to examples, documentation or explanations would be greatly appreciated as this seems to be a relatively new way of creating a dynamic inventory and I am finding it hard to locate clear, detailed documentation.
Edit
Using group variables as suggested by #larsks in the comments worked. Was initially caught out by the fact that the SSH key names returned from the inventory plugin prepend an underscore so the group names need to be of the form _SSHkey.
The answer was to use group variables as suggested in the comments. SSH key names returned from the inventory plugin prepend an underscore so the group names need to be of the form _SSHkey.
Have you considered using the ssh config file? ~/.ssh/config. You can put specific host connection information there. Host, hostname,user,Identityfile are the four options you need
Host ec1
Hostname 10.10.10.10
User ubuntu
IdentityFile ~/.ssh/ec1-ubuntu.rsa
Then when you ssh to 'ec1' , ssh will connect to host 10.10.10.10 as user ubuntu with the specified rsa key. 'Ec1' can be any name you like it does not have to be actual host name or ip or FQDN. Make it match your inventory name.
Warning:: make certain file permissions for the directory ~/.ssh and the files within it are all 0600 (chmod -R 0600 ~/.ssh) and that the owner is correct or ssh will give you fits. On ubuntu the /var/log/auth.log will help with troubleshooting.

How can I provision IIS on EC2 Windows with a resource?

I have just started working on a project that is hosted on an AWS EC2 Windows Instance with an IIS. I want to move this setup to more reliable place, and one of the first things I wanted to do was to move away from snowflake servers that are setup and configured by hand.
So started looking at Terraform from Hashicorp. My thought was that I could define the entire setup including network etc in Terraform and that way make sure it was configured correctly.
I thought I would start with defining a server. A simple Windows Server instance with an IIS installed. But this is where I run into my first problems. I thought I could configure the IIS from Terraform. I guess you can't. So my next thought was to combine Terraform with Powershell Desired State Configuration.
I can setup an IIS server on a box using DSC. But I am stuck invoking DSC from Terraform. I can provision a vanilla server easily. I have tried looking for a good blog post on how to use DSC in combination with Terraform, but I can't find one that explains how to do it.
Can anyone point me towards a good place to read up on this? Or alternatively if the reason I can't find this is that it is just bad practice and I should do it in another way, then please educate me.
Thanks
How can I provision IIS on EC2 Windows with a resource?
You can run arbitrary PowerShell scripts on startup as follows:
resource "aws_instance" "windows_2016_server" {
//...
user_data = <<-EOF
<powershell>
$file = $env:SystemRoot + "\Temp\${var.some_variable}" + (Get-Date).ToString("MM-dd-yy-hh-mm")
New-Item $file -ItemType file
</powershell>
EOF
//...
}
You'll need a variable like this defined to use that (I'm providing a more complex example so there's a more useful starting point)
variable "some_variable" {
type = string
default = "UserDataTestFile"
}
Instead of creating a timestamp file like the example above, you can invoke DSC to set up IIS as you normally would interactively from PowerShell on a server.
You can read more about user_data on Windows here:
https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html
user_data will include your PowerShell directly.
You can use a templatefile("${module.path}/user-data.ps1, {some_variable = var.some_variable}) instead of an inline script as above.
Have user-data.ps1 in the same directory as the TF file that references it:
<powershell>
$file = $env:SystemRoot + "\Temp\${some_variable}" + (Get-Date).ToString("MM-dd-yy-hh-mm")
New-Item $file -ItemType file
</powershell>
You still need the <powershell></powershell> tags around your script source code. That's a requirement of how Windows on EC2 expects PowerShell user-data scripts.
And then update your TF file as follows:
resource "aws_instance" "windows_2016_server" {
//...
user_data = templatefile("${module.path}/user-data.ps1, {
some_variable = var.some_variable
})
//...
}
Note that in the file read by templatefile has variables like some_variable and NOT var.some_variable.
Read more about templatefile here:
https://www.terraform.io/docs/configuration/functions/templatefile.html

Get-WmiObject Win32_ServerFeature Access Remote Server Roles and features

Accessing Roles and Features from the Remote server.
i tries the following PowerShell script to get the roles and features from the remote server.
Get-WmiObject -Computer "serverName" -query 'select * from Win32_ServerFeature'
but the problem is i could not identify additional details like if the given object from the collection is Feature or role. Any help please?
Finally i found another alternative by using Get-WindowsFeature -ComputerName where i can filter featuretype and get separate results for roles and features for remote machines.
For example:
Get-WindowsFeature -ComputerName $ServerName | Where-Object {($_.InstallState -eq “installed”) -and ($_.FeatureType -eq “Role Service”)}

How can we know if a snapshot (taken in ESXi) is reverted or not?

I have a ESXi host running a bunch of VMs. All the VMs have their own snapshots taken periodically. My question is how do we know if a given snapshot is committed (applied) or not using both powerCLI and manually(GUI)
PowerCli:
Once you have connected to the appropriate vCenter server/ESXi host.
$snapShot = get-vm -name $foo | get-snapshot
This will return a Snapshot-Object, as detailed here:
https://www.vmware.com/support/developer/PowerCLI/PowerCLI41U1/html/Snapshot.html
From there you can:
$snapShot | get-member
to see what properties you have to work with.
As for The Gui:
Simply right click the vm > snapshot > snapshot manager
Then you will see a hierarchical list of snapshots and also where you currently are in the list.

amazon EC2 command line interface not returning all my snapshots

So I am tasked with creating a Batch script to handle creating and deleting snapshots of one of our servers. Well I have most of it working but the problem I am having is trying to list out more than 11 snapshots. We have well over 200 snapshots on one volume.
I've tried ec2-describe-snapshots -F "volume-id=vol-12345" -F "status=completed"|sort /R /+49 where vol-12345 is my volume id of course. That does do the proper sorting by date that I need but it still only returns 11 snapshots. I also tried to throw a -a at the end in case there were any private snapshots but I was still getting only 11.
I did see this post: how to list all the snapshots created from a single volume ID EC2 instance but that doesnt quite answer my question on how to display more than 11 snapshots. Any help on this would be greatly appreciated! Thanks.
Here's an alternative, using the AWS Tools for PowerShell. This utility should already be installed if your Windows EC2 is based off of an AMI that Amazon provided.
This example describes a collection of snapshots that you created, and is filtered by status "completed" and by your provided volumeId. It is sorted by StartTime.
# Create a filter to limit by status = completed
$filterByStatusCompleted = New-Object Amazon.EC2.Model.Filter -Property #{Name = "status"; Value = "completed"}
# Create a filter to limit by specific volume ID
$filterByVolumeId = New-Object Amazon.EC2.Model.Filter -Property #{Name = "volume-id"; Value = "vol-11111111"}
# Describe the collection of snapshots, sorted by StartTime
Get-EC2Snapshot -OwnerIds self -Filter $filterByStatusCompleted, $filterByVolumeId | Sort -Property StartTime
Documentation:
AWS Tools For PowerShell - Get-EC2 Snapshot