How to self terminate EC2 from powershell? - amazon-web-services

I need powershell code to terminate an instance without hardcoding the instance ID.
I tried
aws ec2 terminate-instances --instance-ids 'curl http://169.254.169.254/latest/meta-data/instance-id'
But the instance doesn't terminate. Any ideas?

As mentioned in the comments, I suggest working with AWS Powershell Module.
The following code terminate an instance based on ID and Region.
Install-Module AWSPowerShell
Import-Module AWSPowerShell
#Set AWS Credential
Set-AWSCredential -AccessKey "AccessKey" -SecretKey "SecretKey"
#Remove EC2 Insatnace
Remove-EC2Instance -InstanceId "InstanceId" -Region "Region" -Force
How to create new AccessKey and SecretKey - Managing Access Keys for Your AWS Account.
AWSPowerShell Module installation.
From the docs:
Terminates a stopped or running Amazon EC2 instance, prompting for
confirmation before proceeding.
Note that terminated instances will remain visible after termination
(for approximately one hour). The Terminate operation is idempotent;
if you terminate an instance more than once, each call will succeed.
AWS Tools for PowerShell - Remove-EC2Instance Documtnetion.

In my case, I was able to set this attribute at instance launch (using some python code in the lambda that launches the instance) InstanceInitiatedShutdownBehavior='terminate'
then in powershell simply
shutdown /s /t 0
If InstanceInitiatedShutdownBehavior='terminate' is not set, then I believe the default is to stop (as opposed to terminate)

Related

AWS PowerShell error Insufficient privileges to perform this action

I am new to using AWS PowerShell and I am having issues with executing commands in PowerShell. Specifically, I am having issues running the below command. When I log into an AWS EC2 and execute the same command in CLI using the same account credentials it runs without failure. The error I receive states "Insufficient privileges to perform this action." I even went as far as using the admin account and I still receive the same error. I do not believe this matters, but I am running PowerShell on my local PC. Any guidance would be appreciated.
Command that generates the error
aws backup list-recovery-points-by-backup-vault --backup-vault-name Default --max-results 10000
PowerShell script I created for this purpose
Set-AWSCredential `
-AccessKey XXXXXXXXX `
-SecretKey XXXXXXXXX/XXXXXXX`
-StoreAs "MyProfile"
aws backup list-recovery-points-by-backup-vault --backup-vault-name Default --max-results 10000
Your Set-AWSCredential command is creating a profile named "MyProfile", But your aws command is not specifying which profile to use (aws backup --profile MyProfile ...) so its using one called "default"/ignoring the credentials hence you get an accessed denied.
It shouldnt work on Ec2... unless it has a role attached that already grants these same permissions or better (which gets assigned to the "default" profile as the instance starts)
The error was misleading and I was able to get this working to obtain my ultimate goal to delete recovery points by using the below script. The command I was running was not the correct command to be running for this operation.
Set-AWSCredential `
-AccessKey XXXXXX `
-SecretKey XXXXXXX `
-StoreAs "<ProfileName>"
$backups = Get-BAKRecoveryPointsByBackupVaultList -BackupVaultName Default
foreach ($backup in $backups)
{
Remove-BAKRecoveryPoint -BackupVaultName Default -RecoveryPointArn $backup.RecoveryPointArn -Confirm -Force
}

Can't run Powershell user data scripts on Windows EC2

I am using the Javascript SDK to run Windows Server2019 EC2 instances - the AMI I'm using is a custom AMI. Through the SDK, I'm inputting this user data:
<powershell>
Copy-S3Object -BucketName mybucket -KeyPrefix myprefix -LocalFolder C:\Users\myuser\Desktop -Region ap-southeast-2
</powershell>
<persist>true</persist>
When I select the running instance and view user data, the above user data correctly shows.
I have added the appropriate IAM role to the instance as it works when I manually run the base Windows Server2019 instance from the console with the same user data and IAM role.
But when running it from the SDK, the EC2 logs show that:
<powershell> tag was provided.. running powershell content
Failed to get metadata: The result from http://169.254.169.254/latest/user-data was empty
Unable to execute userdata: Userdata was not provided
The trick was to create the AMI using sysprep as shown here.

How to automatically start, execute and stop EC2?

I want to test my Python library in GPU machine once a day.
I decided to use AWS EC2 for testing.
However, the fee of gpu machine is very high, so I want to stop the instance after the test ends.
Thus, I want to do the followings once a day automatically
Start EC2 instance (which is setup manually)
Execute command (test -> push logs to S3)
Stop EC2 (not remove)
How to do this?
It is very simple...
Run script on startup
To run a script automatically when the instance starts (every time it starts, not just the first time), put your script in this directory:
/var/lib/cloud/scripts/per-boot/
Stop instance when test has finished
Simply issue a shutdown command to the operating system at the end of your script:
sudo shutdown now -h
You can push script logs to custom coudwatch namespaces. Like when the process ends publish a state to cloudwatch. In cloudwatch create alarms based on the state of process, so if it has a completed state trigger an AWS lambda function that will stop instance after completion of your job.
Also if you want to start and stop on specific time you can use ec2 instance scheduler to start/stop instances. It just works like a cron job at specific intervals.
You can use the aws cli
To start an instance you would do the following
aws ec2 start-instances --instance-ids i-1234567890abcdef0
and to stop the instance you would do the following
aws ec2 stop-instances --instance-ids i-1234567890abcdef0
To execute commands inside the machine, you will need to ssh into it and run the commands that you need, then you can use the aws cli to upload files to s3
aws s3 cp test.txt s3://mybucket/test2.txt
I suggest reading the aws cli documentation, you will find most if not all what you need to automate aws commands there.
I created a shell script to start an EC2 instance -if not already running,- connect via SSH and, if you want, run a command.
https://gist.github.com/jotaelesalinas/396812f821785f76e5e36cf928777a12
You can use it in three different ways:
./ec2-start-and-ssh.sh -i <instance id> -s
will show status information about your instance: running state and private and public IP addresses.
./ec2-start-and-ssh.sh -i <instance id>
will connect and leave you inside the default shell.
./ec2-start-and-ssh.sh -i <instance id> <command>
will run whatever command you specify, e.g.:
./ec2-start-and-ssh.sh -i <instance id> ./run.sh
./ec2-start-and-ssh.sh -i <instance id> sudo poweroff
I use the last two commands to run periodic jobs minimizing billing costs.
I hope this helps!

Terminate AWS EC2 instance when SSM Run Command status changes

I would like to (1) launch an AWS EC2 instance, (2) run a shell script (that sends output to an S3 bucket) and (3) terminate the instance automatically when the script terminates, all remotely without logging into the instance. I have managed to get parts (1) and (2) working using the AWS CLI commands aws ec2 run-instances and aws ssm send-command. I am struggling with part (3) - getting the instance to terminate automatically when the script completes.
I have seen in the AWS docs that you can use CloudWatch to monitor the SSM Run Command status, and I thought that this might be a solution - when the status changes, terminate the instance. Is this a feasible option? If so, how do you implement it using AWS CLI?
Within the ssm script, you can issue a command to the operating system to shutdown the computer. If you launched the instance with a Shutdown behavior of Terminate, then this will terminate the instance.
Alternatively, the script can retrieve the Instance ID of the instance it is running on, and issue the aws ec2 terminate-instances command, specifying its own Instance ID.
See: Self-Terminating AWS EC2 Instance?

How to run a script on an EC2 instance remotely?

I have an EC2 instance and I need to download a file from its D drive through my program. Currently, it's a very annoying process because I can't access the instance directly from my local machine. The way what I am doing now is running a script on the instance and the instance uploads the file I need to S3 and my program access S3 to read the file.
Just wonder whether there is any simple way to access the drive on the instance instead of going through S3?
I have used AWS DataPipeline and its task runner to execute scripts on a remote instance. The taskrunner waits for a pipeline event published to its worker group.
http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-using-task-runner.html
I use it to execute shell script and commands on a schedule. The script to run should be uploaded to S3, and the Data pipeline template specifies the script's path. Works great for periodic tasks. You can do anything you want on the remote box via the script.
You cannot directly download the file from EC2, but via s3( or maybe using scp command) from your remote ec2.
But to simplify this annoying process you can use AWS Systems Manager.
AWS Systems Manager Run Command allows you to remotely and securely run set of commands on EC2 as well on-premise server. Below are high-level steps to achieve this.
Attach Instance IAM role:
The ec2 instance must have IAM role with policy AmazonSSMFullAccess. This role enables the instance to communicate with the Systems Manager API.
Install SSM Agent:
The EC2 instance must have SSM agent installed on it. The SSM Agent process the run command requests & configure the instance as per command.
Execute command :
Example usage via AWS CLI:
Execute the following command to retrieve the services running on the instance. Replace Instance-ID with ec2 instance id.
aws ssm send-command --document-name "AWS-RunShellScript" --comment "listing services" --instance-ids "Instance-ID" --parameters commands="service --status-all" --region us-west-2 --output text
More detailed information: https://www.justdocloud.com/2018/04/01/run-commands-remotely-ec2-instances/