aws-ec2 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.rspec +1 -0
 - data/CHANGELOG.md +10 -0
 - data/README.md +19 -15
 - data/docs/example/app/user-data/bootstrap.sh +0 -12
 - data/lib/aws_ec2/cli.rb +8 -3
 - data/lib/aws_ec2/core.rb +25 -4
 - data/lib/aws_ec2/create.rb +19 -9
 - data/lib/aws_ec2/help/upload.md +3 -2
 - data/lib/aws_ec2/profile.rb +10 -1
 - data/lib/aws_ec2/script.rb +19 -3
 - data/lib/aws_ec2/script/compile.rb +2 -2
 - data/lib/aws_ec2/script/compress.rb +1 -1
 - data/lib/aws_ec2/script/templates/ami_creation.sh +12 -0
 - data/lib/aws_ec2/script/templates/auto_terminate.sh +11 -0
 - data/lib/aws_ec2/script/templates/auto_terminate_after_timeout.sh +5 -0
 - data/lib/aws_ec2/script/templates/cloudwatch.sh +3 -0
 - data/lib/aws_ec2/script/templates/extract_aws_ec2_scripts.sh +48 -0
 - data/lib/aws_ec2/script/upload.rb +1 -1
 - data/lib/aws_ec2/scripts/auto_terminate.sh +10 -91
 - data/lib/aws_ec2/scripts/auto_terminate/after_timeout.sh +18 -0
 - data/lib/aws_ec2/scripts/auto_terminate/functions.sh +128 -0
 - data/lib/aws_ec2/scripts/auto_terminate/functions/amazonlinux2.sh +10 -0
 - data/lib/aws_ec2/scripts/auto_terminate/functions/ubuntu.sh +11 -0
 - data/lib/aws_ec2/scripts/auto_terminate/setup.sh +31 -0
 - data/lib/aws_ec2/scripts/cloudwatch.sh +22 -0
 - data/lib/aws_ec2/scripts/cloudwatch/configure.sh +74 -0
 - data/lib/aws_ec2/scripts/cloudwatch/install.sh +4 -0
 - data/lib/aws_ec2/scripts/cloudwatch/service.sh +19 -0
 - data/lib/aws_ec2/scripts/shared/functions.sh +44 -0
 - data/lib/aws_ec2/setting.rb +15 -4
 - data/lib/aws_ec2/template/helper/core_helper.rb +46 -7
 - data/lib/aws_ec2/template/helper/ssh_key_helper.rb +1 -1
 - data/lib/aws_ec2/version.rb +1 -1
 - data/spec/fixtures/demo_project/config/settings.yml +22 -0
 - data/spec/lib/cli_spec.rb +0 -7
 - data/spec/lib/params_spec.rb +71 -0
 - metadata +21 -3
 - data/lib/aws_ec2/scripts/ami_creation.sh +0 -35
 
| 
         @@ -1,95 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/bin/bash -exu
         
     | 
| 
       2 
     | 
    
         
            -
            # The shebang line is here in case there's is currently an empty user-data script.
         
     | 
| 
       3 
     | 
    
         
            -
            # It wont hurt if already there.
         
     | 
| 
       4 
     | 
    
         
            -
            ##################
         
     | 
| 
       5 
     | 
    
         
            -
            # auto_terminate.sh script
         
     | 
| 
       6 
     | 
    
         
            -
            # When creating an AMI, a aws ec2 create-image command is added to the end of
         
     | 
| 
       7 
     | 
    
         
            -
            # the user-data script. Creating AMIs prevent the script going any further.
         
     | 
| 
       8 
     | 
    
         
            -
            #
         
     | 
| 
       9 
     | 
    
         
            -
            # To get around this the this is script is added before that happens.
         
     | 
| 
       10 
     | 
    
         
            -
            #
         
     | 
| 
       11 
     | 
    
         
            -
            # https://stackoverflow.com/questions/27920806/how-to-avoid-heredoc-expanding-variables
         
     | 
| 
       12 
     | 
    
         
            -
            cat >/root/terminate-myself.sh << 'EOL'
         
     | 
| 
       13 
     | 
    
         
            -
            #!/bin/bash -exu
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            # install jq dependencies
         
     | 
| 
       16 
     | 
    
         
            -
            function install_jq() {
         
     | 
| 
       17 
     | 
    
         
            -
              if ! type jq > /dev/null ; then
         
     | 
| 
       18 
     | 
    
         
            -
                wget "https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64"
         
     | 
| 
       19 
     | 
    
         
            -
                mv jq-linux64 /usr/local/bin/jq
         
     | 
| 
       20 
     | 
    
         
            -
                chmod a+x /usr/local/bin/jq
         
     | 
| 
       21 
     | 
    
         
            -
              fi
         
     | 
| 
       22 
     | 
    
         
            -
            }
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            function configure_aws_cli() {
         
     | 
| 
       25 
     | 
    
         
            -
              local home_dir=$1
         
     | 
| 
       26 
     | 
    
         
            -
              # Configure aws cli in case it is not yet configured
         
     | 
| 
       27 
     | 
    
         
            -
              mkdir -p $home_dir/.aws
         
     | 
| 
       28 
     | 
    
         
            -
              if [ ! -f $home_dir/.aws/config ]; then
         
     | 
| 
       29 
     | 
    
         
            -
                EC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
         
     | 
| 
       30 
     | 
    
         
            -
                EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed -e 's:\([0-9][0-9]*\)[a-z]*\$:\\1:'`"
         
     | 
| 
       31 
     | 
    
         
            -
                cat >$home_dir/.aws/config <<CONFIGURE_AWS_CLI
         
     | 
| 
       32 
     | 
    
         
            -
            [default]
         
     | 
| 
       33 
     | 
    
         
            -
            region = $EC2_REGION
         
     | 
| 
       34 
     | 
    
         
            -
            output = json
         
     | 
| 
       35 
     | 
    
         
            -
            CONFIGURE_AWS_CLI
         
     | 
| 
       36 
     | 
    
         
            -
              fi
         
     | 
| 
       37 
     | 
    
         
            -
            }
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
            function terminate_instance() {
         
     | 
| 
       40 
     | 
    
         
            -
              aws ec2 terminate-instances --instance-ids $INSTANCE_ID
         
     | 
| 
       41 
     | 
    
         
            -
            }
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
            # on-demand instance example:
         
     | 
| 
       44 
     | 
    
         
            -
            # $ aws ec2 describe-instances --instance-ids i-09482b1a6e330fbf7 | jq '.Reservations[].Instances[].SpotInstanceRequestId'
         
     | 
| 
       45 
     | 
    
         
            -
            # null
         
     | 
| 
       46 
     | 
    
         
            -
            # spot instance example:
         
     | 
| 
       47 
     | 
    
         
            -
            # $ aws ec2 describe-instances --instance-ids i-08318bb7f33c216bd | jq '.Reservations[].Instances[].SpotInstanceRequestId'
         
     | 
| 
       48 
     | 
    
         
            -
            # "sir-dzci5wsh"
         
     | 
| 
       49 
     | 
    
         
            -
            function cancel_spot_request() {
         
     | 
| 
       50 
     | 
    
         
            -
              aws ec2 cancel-spot-instance-requests --spot-instance-request-ids $SPOT_INSTANCE_REQUEST_ID
         
     | 
| 
       51 
     | 
    
         
            -
            }
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
            ###
         
     | 
| 
       54 
     | 
    
         
            -
            # program starts here
         
     | 
| 
       55 
     | 
    
         
            -
            ###
         
     | 
| 
       56 
     | 
    
         
            -
            export PATH=/usr/local/bin:$PATH
         
     | 
| 
       57 
     | 
    
         
            -
            install_jq
         
     | 
| 
       58 
     | 
    
         
            -
            configure_aws_cli /root
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
            AMI_NAME=$1
         
     | 
| 
       61 
     | 
    
         
            -
            if [ $AMI_NAME != "NO-WAIT" ]; then
         
     | 
| 
       62 
     | 
    
         
            -
              # wait for the ami to be successfully created before terminating the instance
         
     | 
| 
       63 
     | 
    
         
            -
              # https://docs.aws.amazon.com/cli/latest/reference/ec2/wait/image-available.html
         
     | 
| 
       64 
     | 
    
         
            -
              # It will poll every 15 seconds until a successful state has been reached. This will exit with a return code of 255 after 40 failed checks.
         
     | 
| 
       65 
     | 
    
         
            -
              # so it'll wait for 10 mins max
         
     | 
| 
       66 
     | 
    
         
            -
              aws ec2 wait image-available --filters "Name=name,Values=$AMI_NAME" --owners self
         
     | 
| 
       67 
     | 
    
         
            -
            fi
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
            INSTANCE_ID=$(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id)
         
     | 
| 
       71 
     | 
    
         
            -
            SPOT_INSTANCE_REQUEST_ID=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID | jq -r '.Reservations[].Instances[].SpotInstanceRequestId')
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
            # Remove this script so it is only allowed to be ran once ever
         
     | 
| 
       74 
     | 
    
         
            -
            # Or else whenenver we launch the AMI, it will kill itself
         
     | 
| 
       75 
     | 
    
         
            -
            rm -f /root/terminate-myself.sh
         
     | 
| 
       76 
     | 
    
         
            -
            grep -v terminate-myself /etc/rc.d/rc.local > /etc/rc.d/rc.local.tmp
         
     | 
| 
       77 
     | 
    
         
            -
            mv /etc/rc.d/rc.local.tmp /etc/rc.d/rc.local
         
     | 
| 
       78 
2 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
            if [ - 
     | 
| 
       80 
     | 
    
         
            -
               
     | 
| 
      
 3 
     | 
    
         
            +
            if [ $# -eq 0 ]; then
         
     | 
| 
      
 4 
     | 
    
         
            +
              command=$(basename "$0")
         
     | 
| 
      
 5 
     | 
    
         
            +
              echo "Usage: $command WHEN"
         
     | 
| 
      
 6 
     | 
    
         
            +
              echo "Examples:"
         
     | 
| 
      
 7 
     | 
    
         
            +
              echo "  $command now"
         
     | 
| 
      
 8 
     | 
    
         
            +
              echo "  $command later"
         
     | 
| 
      
 9 
     | 
    
         
            +
              exit 1
         
     | 
| 
       81 
10 
     | 
    
         
             
            fi
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
            EOL
         
     | 
| 
       84 
     | 
    
         
            -
            chmod a+x /root/terminate-myself.sh
         
     | 
| 
      
 11 
     | 
    
         
            +
            WHEN=$1 # now or later
         
     | 
| 
       85 
12 
     | 
    
         | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
            # schedule termination upon reboot
         
     | 
| 
       89 
     | 
    
         
            -
            chmod +x /etc/rc.d/rc.local
         
     | 
| 
       90 
     | 
    
         
            -
            echo "/root/terminate-myself.sh <%= @options[:ami_name] %> >> /var/log/terminate-myself.log 2>&1" >> /etc/rc.d/rc.local
         
     | 
| 
       91 
     | 
    
         
            -
            <% else %>
         
     | 
| 
       92 
     | 
    
         
            -
            # terminate immediately
         
     | 
| 
       93 
     | 
    
         
            -
            /root/terminate-myself.sh NO-WAIT >> /var/log/terminate-myself.log 2>&1
         
     | 
| 
       94 
     | 
    
         
            -
            <% end %>
         
     | 
| 
       95 
     | 
    
         
            -
            <% end %>
         
     | 
| 
      
 13 
     | 
    
         
            +
            source /opt/aws-ec2/auto_terminate/functions.sh
         
     | 
| 
      
 14 
     | 
    
         
            +
            terminate "$WHEN"
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/bin/bash -exu
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # This is another copy the /opt/aws-ec2/auto_terminate.sh script because the
         
     | 
| 
      
 4 
     | 
    
         
            +
            # /opt/aws-ec2/auto_terminate.sh also gets removed when it gets called.  Specifically,
         
     | 
| 
      
 5 
     | 
    
         
            +
            # it gets gets removed when "terminate after_ami" is called.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            # There's this extra script that terminates after a timeout because sometimes:
         
     | 
| 
      
 8 
     | 
    
         
            +
            #   1. the script stalls: IE: aws ec2 wait image-available and a custom wait_ami
         
     | 
| 
      
 9 
     | 
    
         
            +
            #      does this.
         
     | 
| 
      
 10 
     | 
    
         
            +
            #   2. the user_data script breaks and stops before finishing, never reaching
         
     | 
| 
      
 11 
     | 
    
         
            +
            #      the terminate_later or terminate_now functions.
         
     | 
| 
      
 12 
     | 
    
         
            +
            #
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            source /opt/aws-ec2/auto_terminate/functions.sh
         
     | 
| 
      
 15 
     | 
    
         
            +
            # remove itself since at jobs survive reboots and if the ami gets created
         
     | 
| 
      
 16 
     | 
    
         
            +
            # successfully we do not want this to be captured as part of the ami
         
     | 
| 
      
 17 
     | 
    
         
            +
            rm -f /opt/aws-ec2/auto_terminate/after_timeout.sh
         
     | 
| 
      
 18 
     | 
    
         
            +
            terminate now # hard code to now since only gets called via an at job
         
     | 
| 
         @@ -0,0 +1,128 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/bin/bash -eux
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Key is that instance will not be terminated if source image is the same as the
         
     | 
| 
      
 4 
     | 
    
         
            +
            # original image id.
         
     | 
| 
      
 5 
     | 
    
         
            +
            function terminate_instance() {
         
     | 
| 
      
 6 
     | 
    
         
            +
              local SOURCE_AMI_ID
         
     | 
| 
      
 7 
     | 
    
         
            +
              local AMI_ID
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              SOURCE_AMI_ID=$(curl -s http://169.254.169.254/latest/meta-data/ami-id)
         
     | 
| 
      
 10 
     | 
    
         
            +
              AMI_ID=$(cat /opt/aws-ec2/data/ami-id.txt | jq -r '.ImageId')
         
     | 
| 
      
 11 
     | 
    
         
            +
              if [ "$SOURCE_AMI_ID" = "$AMI_ID" ]; then
         
     | 
| 
      
 12 
     | 
    
         
            +
                echo "The source ami and ami_id are the same: $AMI_ID"
         
     | 
| 
      
 13 
     | 
    
         
            +
                echo "WILL NOT TERMINATE!"
         
     | 
| 
      
 14 
     | 
    
         
            +
                return
         
     | 
| 
      
 15 
     | 
    
         
            +
              fi
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              INSTANCE_ID=$(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id)
         
     | 
| 
      
 18 
     | 
    
         
            +
              SPOT_INSTANCE_REQUEST_ID=$(aws ec2 describe-instances --instance-ids "$INSTANCE_ID" | jq -r '.Reservations[].Instances[].SpotInstanceRequestId')
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              if [ -n "$SPOT_INSTANCE_REQUEST_ID" ]; then
         
     | 
| 
      
 21 
     | 
    
         
            +
                cancel_spot_request
         
     | 
| 
      
 22 
     | 
    
         
            +
              fi
         
     | 
| 
      
 23 
     | 
    
         
            +
              aws ec2 terminate-instances --instance-ids "$INSTANCE_ID"
         
     | 
| 
      
 24 
     | 
    
         
            +
            }
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            # on-demand instance example:
         
     | 
| 
      
 27 
     | 
    
         
            +
            # $ aws ec2 describe-instances --instance-ids i-09482b1a6e330fbf7 | jq '.Reservations[].Instances[].SpotInstanceRequestId'
         
     | 
| 
      
 28 
     | 
    
         
            +
            # null
         
     | 
| 
      
 29 
     | 
    
         
            +
            # spot instance example:
         
     | 
| 
      
 30 
     | 
    
         
            +
            # $ aws ec2 describe-instances --instance-ids i-08318bb7f33c216bd | jq '.Reservations[].Instances[].SpotInstanceRequestId'
         
     | 
| 
      
 31 
     | 
    
         
            +
            # "sir-dzci5wsh"
         
     | 
| 
      
 32 
     | 
    
         
            +
            function cancel_spot_request() {
         
     | 
| 
      
 33 
     | 
    
         
            +
              aws ec2 cancel-spot-instance-requests --spot-instance-request-ids "$SPOT_INSTANCE_REQUEST_ID"
         
     | 
| 
      
 34 
     | 
    
         
            +
            }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            # When image doesnt exist at all, an empty string is returned.
         
     | 
| 
      
 37 
     | 
    
         
            +
            function ami_state() {
         
     | 
| 
      
 38 
     | 
    
         
            +
              local ami_id
         
     | 
| 
      
 39 
     | 
    
         
            +
              ami_id=$1
         
     | 
| 
      
 40 
     | 
    
         
            +
              aws ec2 describe-images --image-ids "$ami_id" --owners self | jq -r '.Images[].State'
         
     | 
| 
      
 41 
     | 
    
         
            +
            }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            function wait_for_ami() {
         
     | 
| 
      
 44 
     | 
    
         
            +
              local name
         
     | 
| 
      
 45 
     | 
    
         
            +
              name=$1
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              local x
         
     | 
| 
      
 48 
     | 
    
         
            +
              local state
         
     | 
| 
      
 49 
     | 
    
         
            +
              x=0
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              state=$(ami_state "$name")
         
     | 
| 
      
 52 
     | 
    
         
            +
              while [ "$x" -lt 10 ] && [ "$state" != "available" ]; do
         
     | 
| 
      
 53 
     | 
    
         
            +
                x=$((x+1))
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                state=$(ami_state "$name")
         
     | 
| 
      
 56 
     | 
    
         
            +
                echo "state $state"
         
     | 
| 
      
 57 
     | 
    
         
            +
                echo "sleeping for 60 seconds... times out at 10 minutes total"
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                type sleep
         
     | 
| 
      
 60 
     | 
    
         
            +
                sleep 60
         
     | 
| 
      
 61 
     | 
    
         
            +
              done
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              echo "final state $state"
         
     | 
| 
      
 64 
     | 
    
         
            +
            }
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            function terminate() {
         
     | 
| 
      
 67 
     | 
    
         
            +
              local when
         
     | 
| 
      
 68 
     | 
    
         
            +
              when=$1
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
              export PATH=/usr/local/bin:$PATH # for jq
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              if [ "$when" == "later" ]; then
         
     | 
| 
      
 73 
     | 
    
         
            +
                terminate_later
         
     | 
| 
      
 74 
     | 
    
         
            +
              elif [ "$when" == "after_ami" ]; then
         
     | 
| 
      
 75 
     | 
    
         
            +
                terminate_after_ami
         
     | 
| 
      
 76 
     | 
    
         
            +
              elif [ "$when" == "after_timeout" ]; then
         
     | 
| 
      
 77 
     | 
    
         
            +
                terminate_after_timeout
         
     | 
| 
      
 78 
     | 
    
         
            +
              else
         
     | 
| 
      
 79 
     | 
    
         
            +
                terminate_now
         
     | 
| 
      
 80 
     | 
    
         
            +
              fi
         
     | 
| 
      
 81 
     | 
    
         
            +
            }
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            function terminate_later() {
         
     | 
| 
      
 84 
     | 
    
         
            +
              schedule_termination
         
     | 
| 
      
 85 
     | 
    
         
            +
            }
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            # This gets set up at the very beginning of the user_data script.  This ensures
         
     | 
| 
      
 88 
     | 
    
         
            +
            # that after a 45 minute timeout the instance will get cleaned up and terminated.
         
     | 
| 
      
 89 
     | 
    
         
            +
            function terminate_after_timeout() {
         
     | 
| 
      
 90 
     | 
    
         
            +
              rm -f /opt/aws-ec2/data/ami-id.txt # rm file possible stale file from previous ami
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              # Remove all old at jobs.
         
     | 
| 
      
 93 
     | 
    
         
            +
              # Assume all at job are previous after_timeout.sh job from previous AMI.
         
     | 
| 
      
 94 
     | 
    
         
            +
              # Note: Each new at job increments the id by 1.  So each AMI will have a different
         
     | 
| 
      
 95 
     | 
    
         
            +
              # at job number.
         
     | 
| 
      
 96 
     | 
    
         
            +
              for i in $(atq | awk '{print $1}') ; do
         
     | 
| 
      
 97 
     | 
    
         
            +
                at -r $i
         
     | 
| 
      
 98 
     | 
    
         
            +
              done
         
     | 
| 
      
 99 
     | 
    
         
            +
              echo "/opt/aws-ec2/auto_terminate/after_timeout.sh now" | at now + 45 minutes
         
     | 
| 
      
 100 
     | 
    
         
            +
            }
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            function terminate_after_ami() {
         
     | 
| 
      
 103 
     | 
    
         
            +
              local AMI_ID
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
              unschedule_termination
         
     | 
| 
      
 106 
     | 
    
         
            +
              AMI_ID=$(cat /opt/aws-ec2/data/ami-id.txt | jq -r '.ImageId')
         
     | 
| 
      
 107 
     | 
    
         
            +
              if [ -n "$AMI_ID" ]; then
         
     | 
| 
      
 108 
     | 
    
         
            +
                # wait for the ami to be successfully created before terminating the instance
         
     | 
| 
      
 109 
     | 
    
         
            +
                # https://docs.aws.amazon.com/cli/latest/reference/ec2/wait/image-available.html
         
     | 
| 
      
 110 
     | 
    
         
            +
                # It will poll every 15 seconds until a successful state has been reached. This will exit with a return code of 255 after 40 failed checks.
         
     | 
| 
      
 111 
     | 
    
         
            +
                # so it'll wait for 10 mins max
         
     | 
| 
      
 112 
     | 
    
         
            +
                # aws ec2 wait image-available --image-ids "$AMI_ID" --owners self
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                # For some reason aws ec2 wait image-available didnt work for amazonlinux2
         
     | 
| 
      
 115 
     | 
    
         
            +
                # so using a custom version
         
     | 
| 
      
 116 
     | 
    
         
            +
                wait_for_ami "$AMI_ID"
         
     | 
| 
      
 117 
     | 
    
         
            +
              fi
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
              terminate_instance
         
     | 
| 
      
 120 
     | 
    
         
            +
            }
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
            function terminate_now() {
         
     | 
| 
      
 123 
     | 
    
         
            +
              terminate_instance
         
     | 
| 
      
 124 
     | 
    
         
            +
            }
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            source "/opt/aws-ec2/shared/functions.sh"
         
     | 
| 
      
 127 
     | 
    
         
            +
            os=$(os_name)
         
     | 
| 
      
 128 
     | 
    
         
            +
            source "/opt/aws-ec2/auto_terminate/functions/${os}.sh"
         
     | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/bin/bash -eux
         
     | 
| 
      
 2 
     | 
    
         
            +
            function schedule_termination() {
         
     | 
| 
      
 3 
     | 
    
         
            +
              chmod +x /etc/rc.d/rc.local
         
     | 
| 
      
 4 
     | 
    
         
            +
              echo "/opt/aws-ec2/auto_terminate.sh after_ami >> /var/log/auto-terminate.log 2>&1" >> /etc/rc.d/rc.local
         
     | 
| 
      
 5 
     | 
    
         
            +
            }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            function unschedule_termination() {
         
     | 
| 
      
 8 
     | 
    
         
            +
              grep -v auto_terminate.sh /etc/rc.d/rc.local > /etc/rc.d/rc.local.tmp
         
     | 
| 
      
 9 
     | 
    
         
            +
              mv /etc/rc.d/rc.local.tmp /etc/rc.d/rc.local
         
     | 
| 
      
 10 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/bin/bash -eux
         
     | 
| 
      
 2 
     | 
    
         
            +
            function schedule_termination() {
         
     | 
| 
      
 3 
     | 
    
         
            +
              chmod +x /etc/rc.local
         
     | 
| 
      
 4 
     | 
    
         
            +
              sed -i 's/exit 0//' /etc/rc.local
         
     | 
| 
      
 5 
     | 
    
         
            +
              echo "/opt/aws-ec2/auto_terminate.sh after_ami >> /var/log/auto-terminate.log 2>&1" >> /etc/rc.local
         
     | 
| 
      
 6 
     | 
    
         
            +
            }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            function unschedule_termination() {
         
     | 
| 
      
 9 
     | 
    
         
            +
              grep -v terminate-myself /etc/rc.local > /etc/rc.local.tmp
         
     | 
| 
      
 10 
     | 
    
         
            +
              mv /etc/rc.local{.tmp,}
         
     | 
| 
      
 11 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/bin/bash -eux
         
     | 
| 
      
 2 
     | 
    
         
            +
            function install_jq() {
         
     | 
| 
      
 3 
     | 
    
         
            +
              if ! type jq > /dev/null ; then
         
     | 
| 
      
 4 
     | 
    
         
            +
                wget "https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64"
         
     | 
| 
      
 5 
     | 
    
         
            +
                mv jq-linux64 /usr/local/bin/jq
         
     | 
| 
      
 6 
     | 
    
         
            +
                chmod a+x /usr/local/bin/jq
         
     | 
| 
      
 7 
     | 
    
         
            +
              fi
         
     | 
| 
      
 8 
     | 
    
         
            +
            }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            function configure_aws_cli() {
         
     | 
| 
      
 11 
     | 
    
         
            +
              local home_dir
         
     | 
| 
      
 12 
     | 
    
         
            +
              home_dir=${1:-/root} # default to /root
         
     | 
| 
      
 13 
     | 
    
         
            +
              # Configure aws cli in case it is not yet configured
         
     | 
| 
      
 14 
     | 
    
         
            +
              mkdir -p "$home_dir/.aws"
         
     | 
| 
      
 15 
     | 
    
         
            +
              if [ ! -f "$home_dir/.aws/config" ]; then
         
     | 
| 
      
 16 
     | 
    
         
            +
                EC2_AVAIL_ZONE=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
         
     | 
| 
      
 17 
     | 
    
         
            +
                EC2_REGION=${EC2_AVAIL_ZONE::-1}
         
     | 
| 
      
 18 
     | 
    
         
            +
                cat >"$home_dir/.aws/config" <<CONFIGURE_AWS_CLI
         
     | 
| 
      
 19 
     | 
    
         
            +
            [default]
         
     | 
| 
      
 20 
     | 
    
         
            +
            region = $EC2_REGION
         
     | 
| 
      
 21 
     | 
    
         
            +
            output = json
         
     | 
| 
      
 22 
     | 
    
         
            +
            CONFIGURE_AWS_CLI
         
     | 
| 
      
 23 
     | 
    
         
            +
              fi
         
     | 
| 
      
 24 
     | 
    
         
            +
            }
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            function setup() {
         
     | 
| 
      
 27 
     | 
    
         
            +
              install_jq
         
     | 
| 
      
 28 
     | 
    
         
            +
              configure_aws_cli /root
         
     | 
| 
      
 29 
     | 
    
         
            +
            }
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            setup
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/bin/bash -eux
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            if [ $# -eq 0 ]; then
         
     | 
| 
      
 4 
     | 
    
         
            +
              command=$(basename "$0")
         
     | 
| 
      
 5 
     | 
    
         
            +
              echo "Usage: $command LOG_GROUP_NAME"
         
     | 
| 
      
 6 
     | 
    
         
            +
              echo "Examples:"
         
     | 
| 
      
 7 
     | 
    
         
            +
              echo "  $command aws-ec2"
         
     | 
| 
      
 8 
     | 
    
         
            +
              echo "  $command ec2"
         
     | 
| 
      
 9 
     | 
    
         
            +
              exit 1
         
     | 
| 
      
 10 
     | 
    
         
            +
            fi
         
     | 
| 
      
 11 
     | 
    
         
            +
            LOG_GROUP_NAME=$1
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            source "/opt/aws-ec2/shared/functions.sh"
         
     | 
| 
      
 14 
     | 
    
         
            +
            os=$(os_name)
         
     | 
| 
      
 15 
     | 
    
         
            +
            if [ "$os" != "amazonlinux2" ]; then
         
     | 
| 
      
 16 
     | 
    
         
            +
              echo "Sorry, enable cloudwatch logging with the aws-ec2 tool is only supported for amazonlinux2 currently"
         
     | 
| 
      
 17 
     | 
    
         
            +
              exit
         
     | 
| 
      
 18 
     | 
    
         
            +
            fi
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            /opt/aws-ec2/cloudwatch/install.sh
         
     | 
| 
      
 21 
     | 
    
         
            +
            /opt/aws-ec2/cloudwatch/configure.sh "$LOG_GROUP_NAME"
         
     | 
| 
      
 22 
     | 
    
         
            +
            /opt/aws-ec2/cloudwatch/service.sh
         
     | 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/bin/bash -eux
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            if [ $# -eq 0 ]; then
         
     | 
| 
      
 4 
     | 
    
         
            +
              command=$(basename "$0")
         
     | 
| 
      
 5 
     | 
    
         
            +
              echo "Usage: $command LOG_GROUP_NAME"
         
     | 
| 
      
 6 
     | 
    
         
            +
              echo "Examples:"
         
     | 
| 
      
 7 
     | 
    
         
            +
              echo "  $command aws-ec2"
         
     | 
| 
      
 8 
     | 
    
         
            +
              echo "  $command ec2"
         
     | 
| 
      
 9 
     | 
    
         
            +
              exit 1
         
     | 
| 
      
 10 
     | 
    
         
            +
            fi
         
     | 
| 
      
 11 
     | 
    
         
            +
            LOG_GROUP_NAME=$1
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # Inject the CloudWatch Logs configuration file contents
         
     | 
| 
      
 14 
     | 
    
         
            +
            cat > /etc/awslogs/awslogs.conf <<- EOF
         
     | 
| 
      
 15 
     | 
    
         
            +
            [general]
         
     | 
| 
      
 16 
     | 
    
         
            +
            state_file = /var/lib/awslogs/agent-state
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            [/var/log/dmesg]
         
     | 
| 
      
 19 
     | 
    
         
            +
            file = /var/log/dmesg
         
     | 
| 
      
 20 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 21 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/log/dmesg
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            [/var/log/messages]
         
     | 
| 
      
 24 
     | 
    
         
            +
            file = /var/log/messages
         
     | 
| 
      
 25 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 26 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/log/messages
         
     | 
| 
      
 27 
     | 
    
         
            +
            datetime_format = %b %d %H:%M:%S
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            [/var/log/cloud-init.log]
         
     | 
| 
      
 30 
     | 
    
         
            +
            file = /var/log/cloud-init.log
         
     | 
| 
      
 31 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 32 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/log/cloud-init.log
         
     | 
| 
      
 33 
     | 
    
         
            +
            datetime_format =
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            [/var/log/cloud-init-output.log]
         
     | 
| 
      
 36 
     | 
    
         
            +
            file = /var/log/cloud-init-output.log
         
     | 
| 
      
 37 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 38 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/log/cloud-init-output.log
         
     | 
| 
      
 39 
     | 
    
         
            +
            datetime_format =
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            [/var/log/secure]
         
     | 
| 
      
 42 
     | 
    
         
            +
            file = /var/log/secure
         
     | 
| 
      
 43 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 44 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/log/secure
         
     | 
| 
      
 45 
     | 
    
         
            +
            datetime_format =
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            [/var/log/audit/audit.log]
         
     | 
| 
      
 48 
     | 
    
         
            +
            file = /var/log/audit/audit.log
         
     | 
| 
      
 49 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 50 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/log/audit/audit.log
         
     | 
| 
      
 51 
     | 
    
         
            +
            datetime_format =
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            [/var/lib/cloud/instance/user-data.txt]
         
     | 
| 
      
 54 
     | 
    
         
            +
            file = /var/lib/cloud/instance/user-data.txt
         
     | 
| 
      
 55 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 56 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/lib/cloud/instance/user-data.txt
         
     | 
| 
      
 57 
     | 
    
         
            +
            datetime_format =
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            [/var/log/messages]
         
     | 
| 
      
 60 
     | 
    
         
            +
            file = /var/log/messages
         
     | 
| 
      
 61 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 62 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/log/messages
         
     | 
| 
      
 63 
     | 
    
         
            +
            datetime_format =
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            [/var/log/auto-terminate.log]
         
     | 
| 
      
 66 
     | 
    
         
            +
            file = /var/log/auto-terminate.log
         
     | 
| 
      
 67 
     | 
    
         
            +
            log_group_name = ${LOG_GROUP_NAME}
         
     | 
| 
      
 68 
     | 
    
         
            +
            log_stream_name = {instance_id}/var/log/auto-terminate.log
         
     | 
| 
      
 69 
     | 
    
         
            +
            datetime_format =
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            region=$(curl 169.254.169.254/latest/meta-data/placement/availability-zone | sed s'/.$//')
         
     | 
| 
      
 74 
     | 
    
         
            +
            sed -i -e "s/region = us-east-1/region = $region/g" /etc/awslogs/awscli.conf
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            cat > /etc/init/awslogs.conf <<- EOL
         
     | 
| 
      
 2 
     | 
    
         
            +
            #upstart-job
         
     | 
| 
      
 3 
     | 
    
         
            +
            description "Configure and start CloudWatch Logs agent EC2 instance"
         
     | 
| 
      
 4 
     | 
    
         
            +
            author "Tung Nguyen"
         
     | 
| 
      
 5 
     | 
    
         
            +
            start on startup
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            script
         
     | 
| 
      
 8 
     | 
    
         
            +
              exec 2>>/var/log/cloudwatch-logs-start.log
         
     | 
| 
      
 9 
     | 
    
         
            +
              set -x
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              service awslogs start
         
     | 
| 
      
 12 
     | 
    
         
            +
              chkconfig awslogs on
         
     | 
| 
      
 13 
     | 
    
         
            +
            end script
         
     | 
| 
      
 14 
     | 
    
         
            +
            EOL
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            initctl list
         
     | 
| 
      
 17 
     | 
    
         
            +
            initctl reload-configuration
         
     | 
| 
      
 18 
     | 
    
         
            +
            initctl start awslogs
         
     | 
| 
      
 19 
     | 
    
         
            +
            initctl list
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/bin/bash -eux
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            function configure_aws_cli() {
         
     | 
| 
      
 4 
     | 
    
         
            +
              local home_dir
         
     | 
| 
      
 5 
     | 
    
         
            +
              home_dir=${1:-/root} # default to /root
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Configure aws cli in case it is not yet configured
         
     | 
| 
      
 7 
     | 
    
         
            +
              mkdir -p "$home_dir/.aws"
         
     | 
| 
      
 8 
     | 
    
         
            +
              if [ ! -f "$home_dir/.aws/config" ]; then
         
     | 
| 
      
 9 
     | 
    
         
            +
                EC2_AVAIL_ZONE=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
         
     | 
| 
      
 10 
     | 
    
         
            +
                EC2_REGION=${EC2_AVAIL_ZONE::-1}
         
     | 
| 
      
 11 
     | 
    
         
            +
                cat >"$home_dir/.aws/config" <<CONFIGURE_AWS_CLI
         
     | 
| 
      
 12 
     | 
    
         
            +
            [default]
         
     | 
| 
      
 13 
     | 
    
         
            +
            region = $EC2_REGION
         
     | 
| 
      
 14 
     | 
    
         
            +
            output = json
         
     | 
| 
      
 15 
     | 
    
         
            +
            CONFIGURE_AWS_CLI
         
     | 
| 
      
 16 
     | 
    
         
            +
              fi
         
     | 
| 
      
 17 
     | 
    
         
            +
            }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            # Example OS values at this point:
         
     | 
| 
      
 20 
     | 
    
         
            +
            #   Ubuntu
         
     | 
| 
      
 21 
     | 
    
         
            +
            #   Amazon Linux AMI
         
     | 
| 
      
 22 
     | 
    
         
            +
            function os_name() {
         
     | 
| 
      
 23 
     | 
    
         
            +
              # https://askubuntu.com/questions/459402/how-to-know-if-the-running-platform-is-ubuntu-or-centos-with-help-of-a-bash-scri
         
     | 
| 
      
 24 
     | 
    
         
            +
              # Method 1 works for amazonlinux2 and ubuntu
         
     | 
| 
      
 25 
     | 
    
         
            +
              # Method 3 the complex script, did not work for amazonlinux2
         
     | 
| 
      
 26 
     | 
    
         
            +
              local OS
         
     | 
| 
      
 27 
     | 
    
         
            +
              OS=$(gawk -F= '/^NAME/{print $2}' /etc/os-release) # text surrounded by double quotes
         
     | 
| 
      
 28 
     | 
    
         
            +
              # strip surrounding quotes: https://stackoverflow.com/questions/9733338/shell-script-remove-first-and-last-quote-from-a-variable
         
     | 
| 
      
 29 
     | 
    
         
            +
              OS="${OS%\"}"
         
     | 
| 
      
 30 
     | 
    
         
            +
              OS="${OS#\"}"
         
     | 
| 
      
 31 
     | 
    
         
            +
              # Example OS values at this point:
         
     | 
| 
      
 32 
     | 
    
         
            +
              #   Ubuntu
         
     | 
| 
      
 33 
     | 
    
         
            +
              #   Amazon Linux AMI
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              # normalize values
         
     | 
| 
      
 36 
     | 
    
         
            +
              case "$OS" in
         
     | 
| 
      
 37 
     | 
    
         
            +
                Ubuntu)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  echo "ubuntu"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  ;;
         
     | 
| 
      
 40 
     | 
    
         
            +
                *)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  echo "amazonlinux2" # default
         
     | 
| 
      
 42 
     | 
    
         
            +
                  ;;
         
     | 
| 
      
 43 
     | 
    
         
            +
              esac
         
     | 
| 
      
 44 
     | 
    
         
            +
            }
         
     |