shaneoh
shaneoh

Reputation: 494

Use AWS CLI to start instance only if it's status is stopped

I'm running a Jenkins server which is the AWS CLI tools installed and working. The server is running Ubuntu 16.04.3

I can successful run a command to start and stop a particular AWS instance, which is:

aws ec2 start-instances --region eu-west-2 --instance-ids i-65a4sd654as

I can also run a command to find the status of that instance:

aws ec2 describe-instance-status --region eu-west-2 --instance-ids i-65a4sd654as

But what I need to do is run two Jenkins jobs which check the status of a particular instance, and then only runs the start-instances or 'stop-instances' command if the status is stopped or 'running', respectively.

Presumably there is a way to run one command and take the output, then make the next command conditional on that, but I can't figure out how to do this. I need the Jenkins job to show success if any of the following situations occur:

And in all other instances to fail.

There's a wealth of information online about using each command, but nothing I can find about how to stitch them together.

Upvotes: 1

Views: 3446

Answers (2)

John Rotenstein
John Rotenstein

Reputation: 269191

It is often easier to do this type of thing in a programming language.

Here is an example script that I use to stop instances that do not have a particular tag, if they are running. It doesn't exactly match your use-case, but it shows how to retrieve instances and base logic on the status and even instance tags.

#!/usr/bin/env python

import boto.ec2

for region in [region for region in boto.ec2.regions() if region.name not in ['us-gov-west-1', 'cn-north-1']]:
  conn = boto.ec2.connect_to_region(region.name)
  reservations = conn.get_all_instances()
  for r in reservations:
    for i in r.instances:
      action = 'stop'
      if 'cleanup' in i.tags.keys():
        action = i.tags['cleanup'].lower()
      #print region.name, i.id, i.tags, i.state, action

      # Ignore ones marked as "ignore", or already terminated
      if action == 'ignore' or i.state == 'terminated':
        continue

      elif action in ['t', 'terminate']:
        print "Terminating", region.name, i.tags, i.state
        conn.terminate_instances([i.id])

      elif action == 'stop' and i.state != 'stopped':
        print "Stopping", region.name, i.tags, i.state
        conn.stop_instances([i.id])

It basically grabs a list of all instances and chooses a default action of stop. It then looks to see whether there is a cleanup tag on the instance.

If the cleanup tag says ignore, it leaves the instance alone. If the instance is tagged 't' or 'terminate', it terminates the instance. Otherwise, is stops the instance.

Upvotes: 2

maafk
maafk

Reputation: 6876

If you're looking for a one liner on the command line, you could do something like this

if [[ $(aws ec2 describe-instances --instance-ids i-abcd1234defg5678 --query 'Reservations[].Instances[].State[].Name' --output text) = "running" ]] ; then \
    aws ec2 stop-instances --instance-ids i-abcd1234defg5678; \
    elif [[ $(aws ec2 describe-instances --instance-ids i-abcd1234defg5678 --query 'Reservations[].Instances[].State[].Name' --output text) = "stopped" ]] ; then \
    aws ec2 start-instances --instance-ids i-abcd1234defg5678 ; \
    fi

Upvotes: 3

Related Questions