我正在启动一个EC2实例,通过从简单的bash脚本调用
ec2-run-instances
,并希望在该实例上执行进一步的操作(例如关联弹性IP),为此需要实例ID。
该命令类似于ec2-run-instances ami-dd8ea5a9 -K pk.pem -C cert.pem –region eu-west-1 -t c1.medium -n 1,其输出:
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
在这个例子中,i-945af9e3是我之后的id。
所以,我需要一个简单的方法来解析命令返回的id,你该怎么做呢?我的AWK有点生锈…随便使用典型的Linux盒子上的任何工具。 (如果有一种方法直接使用EC2-API工具,一切都会更好,但是没有EC2命令可以返回最近启动的实例的id。)
完成正确的答案,这里是一个shell脚本,它创建一个实例,运行一些命令并删除实例。它以与你的相同的方式使用awk。
#!/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 <stephane+amazon@bortzmeyer.org> # 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}