====== EC2 ======
===== Listing instances =====
root@ftphost02:~/.aws# aws ec2 describe-instances --output table --query 'Reservations[].Instances[].Tags[?Key==`Name`].Value'
-------------------
|DescribeInstances|
+-----------------+
| Node1 |
| FTP |
+-----------------+
root@ftphost02:~/.aws# aws ec2 describe-instances --output table --query 'Reservations[].Instances[].[join(`,`,Tags[?Key==`Name`].Value),State.Name]'
----------------------------
| DescribeInstances |
+--------------+-----------+
| Node1 | running |
| FTP | running |
+--------------+-----------+
OR (Using pipe syntax)
root@ftphost02:~/.aws# aws ec2 describe-instances --output table --query 'Reservations[].Instances[].[Tags[?Key==`Name`] | [0].Value, State.Name]'
----------------------------
| DescribeInstances |
+--------------+-----------+
| Node1 | running |
| FTP | running |
+--------------+-----------+
root@ftphost02:~/.aws# aws ec2 describe-instances --instance-ids i-65b45c6b --output table --query 'Reservations[].Instances[].[join(`,`,Tags[?Key==`Name`].Value),State.Name]'
----------------------------
| DescribeInstances |
+--------------+-----------+
| Node1 | running |
+--------------+-----------+
root@ftphost02:~/.aws# aws ec2 describe-instances --output table --query 'Reservations[].Instances[].[Tags[?Key==`Name`] | [0].Value, InstanceId]'
-------------------------------
| DescribeInstances |
+--------------+--------------+
| Node1 | i-65b45c6b |
| FTP | i-59891e53 |
+--------------+--------------+
===== Controlling instances =====
root@ftphost02:~/.aws# aws ec2 start-instances --instance-ids i-65b45c6b
{
"StartingInstances": [
{
"InstanceId": "i-65b45c6b",
"CurrentState": {
"Code": 0,
"Name": "pending"
},
"PreviousState": {
"Code": 80,
"Name": "stopped"
}
}
]
}
root@ftphost02:~/.aws# aws ec2 stop-instances --instance-ids i-65b45c6b
{
"StoppingInstances": [
{
"InstanceId": "i-65b45c6b",
"CurrentState": {
"Code": 64,
"Name": "stopping"
},
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}
=== State codes ===
| 0| pending |
| 16| running |
| 32| shutting-down |
| 48| terminated |
| 64| stopping |
| 80| stopped |
===== Filters =====
Combining two filters can be either ''AND'' or ''OR''.
==== AND ====
Filters are in separate quotes, note space between two quoted blocks:- \\
''--filters "Name=image-id, Values=ami-07cf57ebf50e78466" "Name=tag-key, Values=aws:autoscaling:groupName" ''
$ aws ec2 describe-instances --filters "Name=image-id, Values=ami-07cf57ebf50e78466" "Name=tag-key, Values=aws:autoscaling:groupName" --query 'Reservations[*].Instances[*].[InstanceId]' --profile nonprod_admin
[
[
[
"i-05c83bdad5311253c"
]
],
[
[
"i-0dbcfbdea9b501851"
]
]
]
==== OR ====
Filters are part of the same quotes:- \\
''--filters "Name=image-id, Values=ami-07cf57ebf50e78466,Name=tag-key, Values=aws:autoscaling:groupName" ''
$ aws ec2 describe-instances --filters "Name=image-id, Values=ami-07cf57ebf50e78466,Name=tag-key, Values=aws:autoscaling:groupName" --query 'Reservations[*].Instances[*].[InstanceId]' --profile nonprod_admin
[
[
[
"i-0983d97f816fdd9ea"
]
],
...edited....
[
[
"i-04d8e1a1de04d6bc6"
]
],
[
[
"i-0dbcfbdea9b501851"
]
]
]
==== Using JMESpath ====
$ aws ec2 describe-instances --filters "Name=image-id, Values=ami-07cf57ebf50e78466" "Name=tag-key, Values=aws:autoscaling:groupName" --query 'Reservations[*].Instances[*].{ImageId:ImageId,Tags:Tags}' --profile nonprod_admin
$ aws ec2 describe-instances --query 'Reservations[].Instances[].[Tags[?contains(`["Name"]`, Key)].Value, State.Name, Platform][][]' --profile nonprod_admin --out=text
$ aws ec2 describe-instances --filters "Name=image-id, Values=ami-0927c25b5177ff0de" --query 'Reservations[*].Instances[*].[Tags[?(Key==`Name`)].Value, State.Name, Platform]' --profile nonprod_admin --out=table
$ aws ec2 describe-instances --profile nonprod_admin | jq --raw-output '.[][].Instances[] | {"InstanceId": .InstanceId, "State": .State.Name, "Name": .Tags[]|select(.Key=="Name").Value, "servicename": .Tags[]|select(.Key=="servicename").Value } | join(", ")'
===== listOfAMI0lderThanX.py =====
#!/usr/bin/env python
import boto3
import datetime
from datetime import date
from datetime import datetime
profile = 'nonprod_admin'
context = 'dummy'
session = boto3.session.Session(profile_name=profile)
ec2 = session.client('ec2')
# ec2 = boto3.client('ec2',region)
def getListOfAMI(agearguments, context):
Regex = agearguments["Regex"]
AGEthreshold = int(agearguments["AGEthreshold"])
AMIlist = []
# get list of all AMI owned by this account, matching the regex
AMIResponse = ec2.describe_images(Filters=[{'Name': 'name', 'Values': [Regex]}, ], Owners=['self'])
for i in AMIResponse['Images']:
AMIname = i['Name']
AMIimageID = i['ImageId']
AMIcreationDate = i['CreationDate']
# convert unicode string to timedate object
AMICreationDateTime = datetime.strptime((i['CreationDate']), '%Y-%m-%dT%H:%M:%S.%fZ')
# only needs days not time, so use date method, likewise now is just days
AMICreationDate = AMICreationDateTime.date()
now = date.today()
# Get age of ami and convert timedelta to contain only days
AMIage = (now - AMICreationDate).days
if AMIage >= AGEthreshold:
olderThanThreshold = True
AMIlist.append(AMIimageID)
else:
olderThanThreshold = False
# print ("AMI", AMIimageID, "Age Threshold ", AGEthreshold, "AMI age ",AMIage, "olderthanthres ", olderThanThreshold)
# print (AMIlist)
# resultDict = {"OlderThanThreshold":olderThanThreshold, "AMIage":AMIage}
return (AMIlist)
AMILIST = getListOfAMI({"Regex": "*JS-AMZN2*", "AGEthreshold": "7"}, context)
print (AMILIST)
===== CheckAMIinUse.py =====
#!/usr/bin/env python
import boto3
import sys
profile = 'nonprod_admin'
session = boto3.session.Session(profile_name=profile)
ec2 = session.client('ec2')
ASsession = boto3.session.Session(profile_name=profile)
ec2as = ASsession.client('autoscaling')
# ec2 = boto3.client('ec2')
# ec2as = boto3.client('autoscaling')
context = ''
def checkAMIinUse(AMIimageID, context):
try:
# print (AMIimageID['ImageID'])
# aws ec2 describe-instances --filters "Name=image-id, Values=ami-0e12cbde3e77cbb98" --query 'Reservations[*].Instances[*].[InstanceId]' --profile nonprod_admin
EC2InUseResponse = ec2.describe_instances(Filters=[{'Name': 'image-id', 'Values': [AMIimageID['ImageID']]}])
except:
return ('Exception! Error with AWS response')
# list comprehension, returns list of instances
EC2instance_ids = [
i["InstanceId"]
for r in EC2InUseResponse["Reservations"]
for i in r["Instances"]
]
# print ('checkAMIinUse: Instances relying on ',AMIimageID, ' are ', EC2instance_ids)
if len(EC2instance_ids) == 0:
EC2AMIinUse = False
else:
EC2AMIinUse = True
# print ('checkAMIinUse: Instances ', EC2AMIinUse)
# test if ASG relies on AMI
# get all ASG and for ech, get the Launch config.
# check each LC for the AMI in AMIimageID
# this gets all asg but have to match lc passed to function within it.
# aws autoscaling describe-auto-scaling-groups --profile nonprod_admin --auto-scaling-group-names "AJS asg1"
# print ('checkAMIinUse: ASG Check if AMI is in use by ASG')
ASGresponse = ec2as.describe_auto_scaling_groups()
ASGresponse1 = ASGresponse['AutoScalingGroups']
ASGAMIinUse = False
for i in ASGresponse1:
LCGroup = i['LaunchConfigurationName']
LCResponse = GetAllLaunchConf(LCGroup)
LC_object = LCResponse['LaunchConfigurations']
for item in LC_object:
# print ('Testing for AMIimageID ', AMIimageID, ' in ', item['ImageId'])
if item['ImageId'] == AMIimageID:
# print('True')
ASGAMIinUse = True
break
if ASGAMIinUse is True:
break
# print ('checkAMIinUse: ASG Ami InUse:- ', ASGAMIinUse )
if EC2AMIinUse or ASGAMIinUse is True:
AMIinUse = True
else:
AMIinUse = False
return (AMIinUse)
def GetAllLaunchConf(LCName):
# aws autoscaling describe-launch-configurations --launch-configuration-names "AJS launchconf1" --profile nonprod_admin
# returns dictionary
GLCresponse = ec2as.describe_launch_configurations(LaunchConfigurationNames=[LCName, ], )
return (GLCresponse)
try:
InUse, EC2instance_ids, ASGAMIinUse = checkAMIinUse({"ImageID": "ami-094ef7a0cbb90a7c1"}, context)
except:
print ('Exception! Not enough arguments supplied.', sys.exc_info())
print (InUse, EC2instance_ids, ASGAMIinUse)
==== Get Latest tagged image (AMI) ====
$ aws ec2 describe-images --filters Name=tag:release,Values=Latest Name=is-public,Values=false --profile nonprod_admin | more
{
"Images": [
{
"Architecture": "x86_64",
"CreationDate": "2019-09-01T09:26:52.000Z",
"ImageId": "ami-01efb7e3b3f79ecf9",
"ImageLocation": "057726927330/JS-AMZN2-AMI-CIS-L2-1567328875",
"ImageType": "machine",
"Public": false,
"OwnerId": "057726927330",
"State": "available",
==== Get Stopped Instances ====
#!/bin/bash
for I in `aws ec2 describe-instances --filters "Name=instance-state-name, Values=stopped" --query 'Reservations[].Instances[].InstanceId' --profile nonprod_admin --out text`
do
aws ec2 describe-instances --instance-ids ${I} --query 'Reservations[*].Instances[*].[Tags[?(Key==`Name`)].Value, InstanceId,State.Name, Platform]' \
--profile nonprod_admin
#--out=table
done
==== Security Groups ====
$ aws ec2 describe-network-interfaces --filters Name=group-id,Values=sg-0f99adeb1ca8f1892 --profile nonprod_admin
{
"NetworkInterfaces": []
}
===== EC2 cli =====
aws ec2 describe-instances --region us-west-2
aws ec2 describe-instances --region us-west-2 --output table --filters "Name=instance-type,Values=t2.small"
# for region in `aws ec2 describe-regions --output text | \
cut -f3`; do aws ec2 describe-instances --region $region \
--query 'Reservations[].Instances[].[PrivateIpAddress,InstanceId,Tags[?Key==`Name`].Value[]]' \
--output text | sed '$!N;s/\n/ /'; \
done
10.0.6.10 i-30d917bb prod-001
10.0.0.112 i-33cc3902 EC2ContainerService-default
10.0.0.4 i-f1602579 prod-002
10.130.200.188 i-7c31a9f4 Repair 01
...edited...
===== EC2 metadata - get public ip address =====
$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 56 100 56 0 0 25282 0 --:--:-- --:--:-- --:--:-- 28000
[ssm-user@ip-10-0-0-251 2048]$ curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-ipv4 -w "\n"
52.25.145.1
$
===== AWS NTP Time =====
Use 169.254.169.123 with ntp or chrony.
server 169.254.169.123 prefer iburst
==== Force timesync with chrony ====
If you get this message:-
$ ./get_repos.sh
An error occurred (InvalidSignatureException) when calling the ListRepositories operation: Signature expired: 20231207T141711Z is now earlier than 20231207T152038Z (20231207T153538Z - 15 min.)
your time may be out by more than AWS allows, use this with chrony to force a reset. ''ntpdate'' will force a resync with the ntpd package. You will need to stop the ''ntpd'' daemon first and then restart it after.
root@ubuntu20:~# chronyd -q 'server time.domain.com iburst'
2023-10-26T15:32:22Z chronyd version 3.5 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 -DEBUG)
2023-10-26T15:32:22Z Initial frequency 5.379 ppm
2023-10-26T15:32:26Z System clock wrong by 1931.782000 seconds (step)
2023-10-26T16:04:38Z chronyd exiting
root@ubuntu20:~#
===== Getting info from within a running instance =====
The 169.254.169.254 address allows access to metadata about an instance from within THAT instance, eg:-
[root@ip-172-31-21-109 ~]# curl http://169.254.169.254/latest/meta-data/ami-id
ami-0f1229ec7823be3db
[root@ip-172-31-21-109 ~]#
[root@ip-172-31-21-109 ~]# curl http://169.254.169.254/latest/meta-data/public-keys/
0=AndrewAWS
[root@ip-172-31-21-109 ~]#
[root@ip-172-31-21-109 ~]# curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/06:b7:e8:98:98:0a/public-hostname/
ec2-34-244-253-26.eu-west-1.compute.amazonaws.com
[root@ip-172-31-21-109 ~]#
===== AWS cli =====
[ec2-user@ip-10-96-10-231 ~]$ aws ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId,Tags[?Key==`Name`].Value|[0], IamInstanceProfile.Arn]' --output table
-----------------------------------------------------------------------------------------------------------------------------------
| DescribeInstances |
+---------------------+---------------------------------+-------------------------------------------------------------------------+
| i-0ec2f28f95c0b4396| MadLib API Tier - AutoScaled | arn:aws:iam::399862743030:instance-profile/MadLib-APIrole |
| i-0fd0f2f4e072463b0| MadLib Save Tier - AutoScaled | arn:aws:iam::399862743030:instance-profile/MadLib-Saverole |
| i-0ac39407f3b79e43b| MadLib API Tier - AutoScaled | arn:aws:iam::399862743030:instance-profile/MadLib-APIrole |
| i-0eba4f6906abf1833| MadLib Web Tier - AutoScaled | arn:aws:iam::399862743030:instance-profile/MadLib-AppRole |
| i-0b558db478ac2bdbc| CommandHost | arn:aws:iam::399862743030:instance-profile/CommandHostInstanceProfile |
| i-09a53d2758f4d749d| MadLib Web Tier - AutoScaled | arn:aws:iam::399862743030:instance-profile/MadLib-AppRole |
| i-03804db70790dc0ed| MadLib Save Tier - AutoScaled | arn:aws:iam::399862743030:instance-profile/MadLib-Saverole |
+---------------------+---------------------------------+-------------------------------------------------------------------------+
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ aws ec2 describe-instances --filter "Name=tag:Name,Values=MadLib Save*" --query 'Reservations[].Instances[].[InstanceId,Tags[?Key==`Name`].Value|[0], IamInstanceProfile.Arn]' --output table
------------------------------------------------------------------------------------------------------------------------
| DescribeInstances |
+---------------------+---------------------------------+--------------------------------------------------------------+
| i-0fd0f2f4e072463b0| MadLib Save Tier - AutoScaled | arn:aws:iam::399862743030:instance-profile/MadLib-Saverole |
| i-03804db70790dc0ed| MadLib Save Tier - AutoScaled | arn:aws:iam::399862743030:instance-profile/MadLib-Saverole |
+---------------------+---------------------------------+--------------------------------------------------------------+
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ aws ec2 describe-instances --filter "Name=tag:Name,Values=MadLib Web*" --query 'Reservations[0].Instances[0].IamInstanceProfile.Arn' --output text
arn:aws:iam::399862743030:instance-profile/MadLib-AppRole
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ appROLEARN=$(aws ec2 describe-instances --filter "Name=tag:Name,Values=MadLib Web*" --query 'Reservations[0].Instances[0].IamInstanceProfile.Arn' --output text)
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ echo ${appROLEARN}
arn:aws:iam::399862743030:instance-profile/MadLib-AppRole
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ aws iam list-instance-profiles --query "InstanceProfiles[?Arn=='$appROLEARN']"
[
{
"InstanceProfileId": "AIPAJJGZDTBTYGJDSLFVM",
"Roles": [
{
"AssumeRolePolicyDocument": {
"Version": "2008-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
]
},
"RoleId": "AROAJ7OSABF7346MV6RIY",
"CreateDate": "2018-10-09T08:06:50Z",
"RoleName": "qls-1577787-84859361afe35637-AppLayerWebSi-AppRole-5CZ1MUJYE8Y4",
"Path": "/",
"Arn": "arn:aws:iam::399862743030:role/qls-1577787-84859361afe35637-AppLayerWebSi-AppRole-5CZ1MUJYE8Y4"
}
],
"CreateDate": "2018-10-09T08:07:07Z",
"InstanceProfileName": "MadLib-AppRole",
"Path": "/",
"Arn": "arn:aws:iam::399862743030:instance-profile/MadLib-AppRole"
}
]
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ aws iam list-instance-profiles --query "InstanceProfiles[?Arn=='$appROLEARN'].Roles[0].RoleName"
[
"qls-1577787-84859361afe35637-AppLayerWebSi-AppRole-5CZ1MUJYE8Y4"
]
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ appROLENAME=$(aws iam list-instance-profiles --query "InstanceProfiles[?Arn=='$appROLEARN'].Roles[0].RoleName" --output text)
[ec2-user@ip-10-96-10-231 ~]$ aws iam list-role-policies --role-name ${appROLENAME}
{
"PolicyNames": [
"MabLib-App-Policy"
]
}
[ec2-user@ip-10-96-10-231 ~]$ appPOLNAME=$(aws iam list-role-policies --role-name ${appROLENAME} --query PolicyNames[] --output text)
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ aws iam get-role-policy --role-name ${appROLENAME} --policy-name ${appPOLNAME}
{
"RoleName": "qls-1577787-84859361afe35637-AppLayerWebSi-AppRole-5CZ1MUJYE8Y4",
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:List*",
"s3:Get*"
],
"Resource": "*",
"Effect": "Allow"
}
]
},
"PolicyName": "MabLib-App-Policy"
}
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ aws deploy list-applications
{
"applications": [
"qls-1577787-84859361afe35637-AppLayerWebSite-1P4CE84PXN67F-MadLibsSite-1AG3943MCP2N9",
"qls-1577787-84859361afe35637-AppStackAPI-FO024805JDNG-MadLibsAPI-1Q30CGWVEPZDA",
"qls-1577787-84859361afe35637-AppStackSave-1O3LTSI3CAKLB-MadLibsSave-XM6SBRZK607M"
]
}
[ec2-user@ip-10-96-10-231 ~]$ aws deploy list-deployments
{
"deployments": [
"d-W13R99NVV",
"d-Y639UTFVV",
"d-EAQ1SUMVV"
]
}
[ec2-user@ip-10-96-10-231 ~]$ DEPLOYARRAY=$(aws deploy list-deployments --output text)
[ec2-user@ip-10-96-10-231 ~]$ IFS=' ' read -r -a DEPLOYID <<< $DEPLOYARRAY
[ec2-user@ip-10-96-10-231 ~]$ echo "${DEPLOYID[1]}"
d-W13R99NVV
[ec2-user@ip-10-96-10-231 ~]$ echo "${DEPLOYID[3]}"
d-Y639UTFVV
[ec2-user@ip-10-96-10-231 ~]$ echo "${DEPLOYID[5]}"
d-EAQ1SUMVV
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ aws deploy list-deployment-instances --deployment-id ${DEPLOYID[1]}
{
"instancesList": [
"i-09a53d2758f4d749d",
"i-0eba4f6906abf1833"
]
}
[ec2-user@ip-10-96-10-231 ~]$ aws ec2 describe-instances --filter "Name=tag:Name,Values=MadLib*" --query 'Reservations[].Instances[].[InstanceId, Tags[?Key==`Name`].Value | [0]]' --output table
----------------------------------------------------------
| DescribeInstances |
+----------------------+---------------------------------+
| i-0ec2f28f95c0b4396 | MadLib API Tier - AutoScaled |
| i-0fd0f2f4e072463b0 | MadLib Save Tier - AutoScaled |
| i-0ac39407f3b79e43b | MadLib API Tier - AutoScaled |
| i-0eba4f6906abf1833 | MadLib Web Tier - AutoScaled |
| i-09a53d2758f4d749d | MadLib Web Tier - AutoScaled |
| i-03804db70790dc0ed | MadLib Save Tier - AutoScaled |
+----------------------+---------------------------------+
[ec2-user@ip-10-96-10-231 ~]$
[ec2-user@ip-10-96-10-231 ~]$ aws deploy get-deployment --deployment-id ${DEPLOYID[1]}
{
"deploymentInfo": {
"applicationName": "qls-1577787-84859361afe35637-AppLayerWebSite-1P4CE84PXN67F-MadLibsSite-1AG3943MCP2N9",
"status": "Succeeded",
"deploymentOverview": {
"Skipped": 0,
"Succeeded": 2,
"Failed": 0,
"Ready": 0,
"InProgress": 0,
"Pending": 0
},
"description": "[CFN-DSHWMLJA] Deploying App MadLibs-Site Version-1.0\n",
"deploymentConfigName": "MadLibs-Site",
"creator": "user",
"fileExistsBehavior": "DISALLOW",
"deploymentId": "d-W13R99NVV",
"deploymentStatusMessages": [],
"ignoreApplicationStopFailures": true,
"autoRollbackConfiguration": {
"enabled": false
},
"deploymentStyle": {
"deploymentType": "IN_PLACE",
"deploymentOption": "WITHOUT_TRAFFIC_CONTROL"
},
"updateOutdatedInstancesOnly": false,
"instanceTerminationWaitTimeStarted": false,
"computePlatform": "Server",
"deploymentGroupName": "WebAppDeplyGroup",
"createTime": 1539072614.847,
"completeTime": 1539072703.42,
"revision": {
"revisionType": "S3",
"s3Location": {
"bundleType": "zip",
"bucket": "us-east-1-tcprod",
"key": "courses/AWS-200-DOP/v2.1.5/lab-1-CLI/scripts/MadLibs-WebSite-Package.zip"
}
}
}
}
[ec2-user@ip-10-96-10-231 ~]$