How To Create An AWS EC2 Instance Using PowerShell
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In this blog post, we will discuss how to create an AWS EC2 instance using PowerShell. We will create a new EC2 instance from scratch including VPC, Subnets, Security Groups, etc.
Prerequisites:
- One Windows system with PowerShell version 5.0 or higher.
- AWSPowerShell module installed and configured with proper access.
You can follow the below blog post to install and configure PowerShell for AWS.
https://cloudaffaire.com/how-to-install-and-configure-powershell-for-aws/
How To Create An AWS EC2 Instance Using PowerShell:
Step 1: Create a new VPC.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
######################################################## ## How To Create An AWS EC2 Instance Using PowerShell ## ######################################################## ## ---------------- ## Create A New VPC ## ---------------- ## Create a VPC $MyVPC = (New-EC2Vpc ` -CidrBlock "10.0.0.0/16" ` -ProfileName " -Region " ## Enable DNS hostname for your VPC Edit-EC2VpcAttribute ` -VpcId $MyVPC.VpcId ` -EnableDnsHostnames $true ` -ProfileName " -Region " |
Step 2: Create a new public subnet on your VPC.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
## -------------------------- ## Create A New Public Subnet ## -------------------------- ## Create a Subnet $MySubnet = (New-EC2Subnet ` -VpcId $MyVPC.VpcId ` -CidrBlock "10.0.1.0/24" ` -AvailabilityZone "ap-south-1a" ` -ProfileName " -Region " ## Enable Auto-assign Public IP on the Subnet Edit-EC2SubnetAttribute ` -SubnetId $MySubnet.SubnetId ` -MapPublicIpOnLaunch $true ` -ProfileName " -Region " ## Create an Internet Gateway $MyInternetGateway = New-EC2InternetGateway ` -ProfileName " -Region " ## Attach Internet gateway to your VPC Add-EC2InternetGateway ` -VpcId $MyVPC.VpcId ` -InternetGatewayId $MyInternetGateway.InternetGatewayId ` -ProfileName " -Region " ## Create a route table $MyRouteTable = (New-EC2RouteTable ` -VpcId $MyVPC.VpcId ` -ProfileName " -Region " ## Create route to Internet Gateway New-EC2Route ` -RouteTableId $MyRouteTable.RouteTableId ` -DestinationCidrBlock "0.0.0.0/0" ` -GatewayId $MyInternetGateway.InternetGatewayId ` -ProfileName " -Region " ## Associate the public subnet with route table $RouteAID = (Register-EC2RouteTable ` -RouteTableId $MyRouteTable.RouteTableId ` -SubnetId $MySubnet.SubnetId ` -ProfileName " -Region " |
Step 3: Create a new security group with port 22 for SSH connection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
## --------------------------- ## Create A New Security Group ## --------------------------- ## Create a security group $MySecurityGroup = $(New-EC2SecurityGroup ` -GroupName "MySecurityGroup" ` -Description "Used for SSH connection" ` -VpcId $MyVPC.VpcId ` -ProfileName " -Region " ## Create security group ingress rules $IpRange = New-Object -TypeName Amazon.EC2.Model.IpRange $IpRange.CidrIp = "0.0.0.0/0" $IpRange.Description = "SSH from Anywhere" $IpPermission = New-Object Amazon.EC2.Model.IpPermission $IpPermission.IpProtocol = "tcp" $IpPermission.ToPort = 22 $IpPermission.FromPort = 22 $IpPermission.Ipv4Ranges = $IpRange Grant-EC2SecurityGroupIngress ` -GroupId $MySecurityGroup ` -IpPermission $IpPermission ` -ProfileName " -Region " |
Step 4: Get the AMI ID for your new EC2 instance. In this demo, I am using Amazon provided Amazon Linux 2 AMI for our EC2 instance. I have also given the code to fetch the latest AMI ID for some popular OS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
## ------------------------------------ ## Get AMI ID For Your New EC2 Instance ## ------------------------------------ ## Amazon Linux 2 AMI $f1 = @{Name="state"; Value="available"} $f2 = @{Name="description"; Value="Amazon Linux 2 AMI 2.0.*x86_64 HVM gp2"} $AMI = (Get-EC2Image ` -Filter @($f1, $f2) ` -ProfileName " -Region " $Image = $AMI | Sort-Object CreationDate -Descending | Select-Object ImageId -First 1 $Image.ImageId ## Amazon Linux AMI ## $f1 = @{Name="state"; Value="available"} ## $f2 = @{Name="description"; Value="Amazon Linux AMI ????.??.?.????????.? x86_64 HVM gp2"} ## $AMI = (Get-EC2Image ` ## -Filter @($f1, $f2) ` ## -ProfileName " ## -Region " ## $Image = $AMI | Sort-Object CreationDate -Descending | Select-Object ImageId -First 1 ## $Image.ImageId ## Red Hat Enterprise Linux 8 AMI ## $f1 = @{Name="state"; Value="available"} ## $f2 = @{Name="name"; Value="RHEL-8.2.0_HVM-????????-x86_64-0-Hourly2-GP2"} ## $AMI = (Get-EC2Image ` ## -Filter @($f1, $f2) ` ## -ProfileName " ## -Region " ## $Image = $AMI | Sort-Object CreationDate -Descending | Select-Object ImageId -First 1 ## $Image.ImageId ## Ubuntu 20 LTS ## $f1 = @{Name="state"; Value="available"} ## $f2 = @{Name="description"; Value="Canonical, Ubuntu, 20.04 LTS, amd64 focal image build on ????-??-??"} ## $AMI = (Get-EC2Image ` ## -Filter @($f1, $f2) ` ## -ProfileName " ## -Region " ## $Image = $AMI | Sort-Object CreationDate -Descending | Select-Object ImageId -First 1 ## $Image.ImageId ## SUSE Linux Enterprise Server 15 ## $f1 = @{Name="state"; Value="available"} ## $f2 = @{Name="description"; Value="SUSE Linux Enterprise Server 15 SP2 (HVM, 64-bit, SSD-Backed)"} ## $AMI = (Get-EC2Image ` ## -Filter @($f1, $f2) ` ## -ProfileName " ## -Region " ## $Image = $AMI | Sort-Object CreationDate -Descending | Select-Object ImageId -First 1 ## $Image.ImageId ## CentOS 7 ## $f1 = @{Name="state"; Value="available"} ## $f2 = @{Name="description"; Value="CentOS Linux 7 x86_64 HVM EBS ENA 2002_01"} ## $AMI = (Get-EC2Image ` ## -Filter @($f1, $f2) ` ## -ProfileName " ## -Region " ## $Image = $AMI | Sort-Object CreationDate -Descending | Select-Object ImageId -First 1 ## $Image.ImageId ## Windows Server 2019 ## $f1 = @{Name="state"; Value="available"} ## $f2 = @{Name="name"; Value="Windows_Server-2019-English-Full-Base-????.??.??"} ## $AMI = (Get-EC2Image ` ## -Filter @($f1, $f2) ` ## -ProfileName " ## -Region " ## $Image = $AMI | Sort-Object CreationDate -Descending | Select-Object ImageId -First 1 ## $Image.ImageId |
Step 5: Create a new key pair and save the key pair to your local system.
1 2 3 4 5 6 7 8 9 10 11 |
## --------------------- ## Create A New Key-Pair ## --------------------- ## Create a new key-pair $myPSKeyPair = (New-EC2KeyPair ` -KeyName "MyVPC-KeyPair" ` -ProfileName " -Region " $myPSKeyPair.KeyMaterial | Out-File -Encoding ascii myPSKeyPair.pem |
Step 6: Create a new EC2 instance using PowerShell.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
## ------------------------- ## Create A New EC2 instance ## ------------------------- ## Create new EC2 instance $MyEC2Instance = (New-EC2Instance ` -ImageId $Image.ImageId ` -AssociatePublicIp $true ` -InstanceType "t2.micro" ` -KeyName "MyVPC-KeyPair" ` -PrivateIpAddress "10.0.1.10" ` -SecurityGroupId $MySecurityGroup ` -SubnetId $MySubnet.SubnetId ` -ProfileName " -Region " ## Get EC2 Instance Details $f1 = @{Name="reservation-id"; Value=$MyEC2Instance.ReservationId} $MyVPCEC2Instance = (Get-EC2Instance ` -Filter @($f1) ` -ProfileName " -Region " $MyVPCEC2Instance |
Step 7: Add a tag to all the resources created in this demo (Optional).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
## ----------------------------------------------------------- ## Create Tags For All Your AWS Resources Created In This Demo ## ----------------------------------------------------------- ## Add a tag to the VPC $tag = New-Object Amazon.EC2.Model.Tag; $tag.Key = "Name"; $tag.Value = "MyVPC" New-EC2Tag ` -Resource $MyVPC.VpcId ` -Tag $tag ` -ProfileName " -Region " ## Add a tag to public subnet $tag = New-Object Amazon.EC2.Model.Tag; $tag.Key = "Name"; $tag.Value = "MyVPC-Public-Subnet" New-EC2Tag ` -Resource $MySubnet.SubnetId ` -Tag $tag ` -ProfileName " -Region " ## Add a tag to the Internet-Gateway $tag = New-Object Amazon.EC2.Model.Tag; $tag.Key = "Name"; $tag.Value = "MyVPC-Internet-Gateway" New-EC2Tag ` -Resource $MyInternetGateway.InternetGatewayId ` -Tag $tag ` -ProfileName " -Region " ## Add a tag to the default route table $f1 = @{Name="association.main"; Value="true"} $f2 = @{Name="vpc-id"; Value=$MyVPC.VpcId} $DefaultRouteTable = (Get-EC2RouteTable ` -Filter @($f1, $f2) ` -ProfileName " -Region " $tag = New-Object Amazon.EC2.Model.Tag; $tag.Key = "Name"; $tag.Value = "MyVPC-Default-Route-Table" New-EC2Tag ` -Resource $DefaultRouteTable.RouteTableId ` -Tag $tag ` -ProfileName " -Region " ## Add a tag to the public route table $tag = New-Object Amazon.EC2.Model.Tag; $tag.Key = "Name"; $tag.Value = "MyVPC-Custom-Route-Table" New-EC2Tag ` -Resource $MyRouteTable.RouteTableId ` -Tag $tag ` -ProfileName " -Region " ## Add a tag to the default security group $f1 = @{Name="group-name"; Value="default"} $f2 = @{Name="vpc-id"; Value=$MyVPC.VpcId} $DefaultSecurityGroup = (Get-EC2SecurityGroup ` -Filter @($f1, $f2) ` -ProfileName " -Region " $tag = New-Object Amazon.EC2.Model.Tag; $tag.Key = "Name"; $tag.Value = "MyVPC-Default-Security-Group" New-EC2Tag ` -Resource $DefaultSecurityGroup.GroupId ` -Tag $tag ` -ProfileName " -Region " ## Add a tag to the custom security group $tag = New-Object Amazon.EC2.Model.Tag; $tag.Key = "Name"; $tag.Value = "MyVPC-Custom-Security-Group" New-EC2Tag ` -Resource $MySecurityGroup ` -Tag $tag ` -ProfileName " -Region " ## Add a tag to the ec2 instance $tag = New-Object Amazon.EC2.Model.Tag; $tag.Key = "Name"; $tag.Value = "MyVPC-EC2-Instance" New-EC2Tag ` -Resource $MyVPCEC2Instance.InstanceId ` -Tag $tag ` -ProfileName " -Region " |
Step 8: Try to connect to your EC2 instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
## ---------------------------- ## Connect To Your EC2 Instance ## ---------------------------- ## Get EC2 Instance Status (Wait till status becomes running) $EC2Status = (Get-EC2InstanceStatus ` -InstanceId $MyVPCEC2Instance.InstanceId ` -ProfileName " -Region " $EC2Status.InstanceState.Name ## Try to connect to the instance ssh -i myPSKeyPair.pem ec2-user@$MyVPCEC2Instance.PublicIpAddress exit |
Step 9: Cleanup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
## ------- ## Cleanup ## ------- ## Terminate the ec2 instance Remove-EC2Instance ` -InstanceId $MyVPCEC2Instance.InstanceId ` -Force ` -ProfileName " -Region " ## Delete key pair Remove-Item -Path .\myPSKeyPair.pem; Remove-EC2KeyPair ` -KeyName "MyVPC-KeyPair" ` -Force ` -ProfileName " -Region " ## Delete custom security group Remove-EC2SecurityGroup ` -GroupId $MySecurityGroup ` -Force ` -ProfileName " -Region " ## Delete internet gateway Dismount-EC2InternetGateway ` -VpcId $MyVPC.VpcId ` -InternetGatewayId $MyInternetGateway.InternetGatewayId ` -Force ` -ProfileName " -Region " Remove-EC2InternetGateway ` -InternetGatewayId $MyInternetGateway.InternetGatewayId ` -Force ` -ProfileName " -Region " ## Delete the custom route table Unregister-EC2RouteTable ` -AssociationId $RouteAID ` -Force ` -ProfileName " -Region " Remove-EC2RouteTable ` -RouteTableId $MyRouteTable.RouteTableId ` -Force ` -ProfileName " -Region " ## Delete the public subnet Remove-EC2Subnet ` -SubnetId $MySubnet.SubnetId ` -Force ` -ProfileName " -Region " ## Delete the vpc Remove-EC2Vpc ` -VpcId $MyVPC.VpcId ` -Force ` -ProfileName " -Region " |
Hope you have enjoyed this blog post. Please refer below AWS documentation for more details
https://docs.aws.amazon.com/powershell/latest/userguide/pstools-ec2-launch.html
https://docs.aws.amazon.com/powershell/latest/reference/