bash - Obtención del ID de una instancia recién lanzada con ec2-api-tools
scripting awk (5)
Como alternativa a las ec2-run-instances
, puede crear una instancia de ec2 y obtener InstanceId por una línea mediante las instancias de run-instances awscli:
export MyServerID=$(aws ec2 run-instances --image-id AMI --count 1 --instance-type t2.micro --key-name "my_ssh_key" --security-group-ids sg-xxx --subnet-id subnet-yyy --query ''Instances[0].InstanceId'' --output text)
Estoy lanzando una instancia de EC2, invocando ec2-run-instances
desde un simple script de bash, y quiero realizar más operaciones en esa instancia (p. Ej., Asociar el elástico IP), para lo cual necesito la identificación de la instancia.
El comando es algo así como ec2-run-instances ami-dd8ea5a9 -K pk.pem -C cert.pem --region eu-west-1 -t c1.medium -n 1
, y su salida:
RESERVATION r-b6ea58c1 696664755663 default
INSTANCE i-945af9e3 ami-dd8ea5b9 pending 0 c1.medium 2010-04-15T10:47:56+0000 eu-west-1a aki-b02a01c4 ari-39c2e94d
En este ejemplo, i-945af9e3
es el id que estoy i-945af9e3
.
Por lo tanto, necesitaría una forma sencilla de analizar el ID de lo que devuelve el comando: ¿cómo lo harías? Mi AWK está un poco oxidado ... No dude en utilizar cualquier herramienta disponible en una caja típica de Linux. (Si hay una manera de obtenerlo directamente utilizando las herramientas de la API de EC2, mucho mejor. Pero afaik no hay un comando de EC2 para, por ejemplo, devolver el ID de la instancia iniciada más recientemente).
Completando su respuesta correcta, aquí hay un script de shell que crea una instancia, ejecuta algunos comandos y elimina la instancia. Utiliza awk de la misma manera que la tuya.
#!/bin/sh
# Creates an Amazon EC2 virtual machine (an instance) and runs some
# shell commands on it before terminating it. Just an example.
# Stephane Bortzmeyer <[email protected]>
# Parameters you can set.
# Choose an AMI you like (ami-02103876 is a Debian "lenny")
AMI=ami-02103876
# Create your key pair first, for instance on the Web interface
KEY=test-b
KEYDIR=.
# The user name to use depends on the AMI. "root" is common but check
# the documentation of the AMI.
USERNAME=root
# Needs to be a legal Unix group of commands
COMMANDS="(uname -a; df -h; cat /etc/debian_version)"
MAX_CONNECTS=4
MAX_TESTS=6
# If you want to change from the default region, set the environment
# variable EC2_URL for instance ''export
# EC2_URL=https://ec2.eu-west-1.amazonaws.com'' to use the ''eu-west-1''
# region
# Also, be sure your default security group allows incoming SSH.
if [ "${EC2_PRIVATE_KEY}" = "" ] || [ "${EC2_CERT}" = "" ]; then
echo "You need to have X.509 certificate and private key locally, and to set the environment variables EC2_PRIVATE_KEY and EC2_CERT to indicate their locations" 1>&2
exit 1
fi
start=$(ec2-run-instances --key ${KEY} $AMI)
if [ $? != 0 ]; then
echo "Machine did not start" 1>&2
exit 1
fi
AMI_E=$(echo "$start" | awk ''/^INSTANCE/ {print $3}'')
if [ "$AMI_E" != "$AMI" ]; then
echo "AMI does not match (got $AMI_E instead of $AMI), the machine probably did not start" 1>&2
exit 1
fi
INSTANCE=$(echo "$start" | awk ''/^INSTANCE/ {print $2}'')
# I do not find a way to block until the machine is ready. We
# apparently have to poll.
OVER=0
TESTS=0
while [ $OVER != 1 ] && [ $TESTS -lt $MAX_TESTS ]; do
description=$(ec2-describe-instances ${INSTANCE})
STATE=$(echo "$description" | awk ''/^INSTANCE/ {print $6}'')
NAME=$(echo "$description" | awk ''/^INSTANCE/ {print $4}'')
if [ "$NAME" = "" ]; then
echo "No instance ${INSTANCE} available. Crashed or was terminated." 1>&2
exit 1
fi
if [ $STATE = "running" ]; then
OVER=1
else
# I like bc but ''echo $(( TESTS+=1 ))'' should work, too. Or expr.
TESTS=$(echo $TESTS+1 | bc)
sleep 2
fi
done
if [ $TESTS = $MAX_TESTS ]; then
echo "${INSTANCE} never got to running state" 1>&2
ec2-terminate-instances ${INSTANCE}
exit 1
fi
echo "$INSTANCE is running, name is $NAME"
# The SSH server does not seem reachable immediately. We again have to poll
OVER=0
TESTS=0
while [ $OVER != 1 ] && [ $TESTS -lt $MAX_CONNECTS ]; do
ssh -o "StrictHostKeyChecking no" -i ${KEYDIR}/${KEY}.pem ${USERNAME}@$NAME "${COMMANDS}"
if [ $? != 255 ]; then
# It means we connected successfully (even if the remote command failed)
OVER=1
else
TESTS=$(echo $TESTS+1 | bc)
sleep 3
fi
done
if [ $TESTS = $MAX_CONNECTS ]; then
echo "Cannot connect to ${NAME}" 1>&2
fi
ec2-terminate-instances ${INSTANCE}
No hay necesidad de usar awk:
# create the instance and capture the instance id
echo "Launching instance..."
instanceid=$(ec2-run-instances --key $pemkeypair --availability-zone $avzone $ami | egrep ^INSTANCE | cut -f2)
if [ -z "$instanceid" ]; then
echo "ERROR: could not create instance";
exit;
else
echo "Launched with instanceid=$instanceid"
fi
de http://www.hulen.com/post/22802124410/unattended-amazon-ec2-install-script
Ok, al menos algo como esto debería funcionar:
instance_id=$(ec2-run-instances ami-dd8ea5a9 [...] | awk ''/INSTANCE/{print $2}'')
Admito que estaba un poco perezoso pensando que es más rápido preguntar en SO que volver a aprender algunos conceptos básicos de AWK ... :-)
Edición : uso de AWK simplificado como sugirió Dennis. También, usando $()
lugar de `` para mayor claridad, y eliminé la variable intermedia.
http://www.tothenew.com/blog/how-to-parse-json-by-command-line-in-linux/
best tool to parse json in shell
#get instance id
cat sample.json | jq ''.Instances[0].InstanceId''|sed -e ''s/^"//'' -e ''s/"$//''
#check instances is running or not
cat status.json | jq ''.InstanceStatuses[0].InstanceState.Name''|sed -e ''s/^"//'' -e ''s/"$//''