Skip to content

auto-scaling-group-cmd

func-create-launch-template-

  • to create launch template, you need: security group id (git/git-mkdocs/CLI/awscli/ec2-cmd) and ami id (git/git-mkdocs/CLI/awscli/ec2-cmd)
    func-create-launch-template
    # depends on: SG_ID, AMI_ID
    # output variable: LAUNCH_TEMPLATE_ID
    # quick link: https://panlm.github.io/CLI/functions/func-create-launch-template.sh
    
    function create-launch-template () {
        OPTIND=1
        OPTSTRING="h?s:a:"
        local SG_ID=""
        local AMI_ID=""
        while getopts ${OPTSTRING} opt; do
            case "${opt}" in
                s) SG_ID=${OPTARG} ;;
                a) AMI_ID=${OPTARG} ;;
                h|\?) 
                    echo "format: create-launch-template -s SG_ID -a AMI_ID"
                    echo
                    return 0
                ;;
            esac
        done
        : ${SG_ID:?Missing -s}
        : ${AMI_ID:?Missing -a}
    
        LAUNCH_TEMPLATE_NAME=launchtemplate-$(TZ=CST-8 date +%Y%m%d-%H%M)
        local TMP=$(mktemp --suffix .${LAUNCH_TEMPLATE_NAME})
        envsubst >${TMP} <<-EOF
    {
        "InstanceType": "m5.large",
        "ImageId": "${AMI_ID}",
        "SecurityGroupIds": [
            "${SG_ID}"
        ],
        "TagSpecifications": [{
            "ResourceType": "instance",
            "Tags": [{
                "Key": "Name",
                "Value": "${LAUNCH_TEMPLATE_NAME}"
            }]
        },
        {
            "ResourceType": "volume",
            "Tags": [{
                "Key": "Name",
                "Value": "${LAUNCH_TEMPLATE_NAME}"
            }]
        }]
    }
    EOF
    
        aws ec2 create-launch-template \
            --launch-template-name ${LAUNCH_TEMPLATE_NAME} \
            --launch-template-data file://${TMP} |tee ${TMP}.out
        LAUNCH_TEMPLATE_ID=$(cat ${TMP}.out |jq -r '.LaunchTemplate.LaunchTemplateId')
        echo "LAUNCH_TEMPLATE_ID="${LAUNCH_TEMPLATE_ID}
    } # funcend
    

    refer: func-create-launch-template

func-create-auto-scaling-group-

  • to create auto scaling group, you need: launch template id
    func-create-auto-scaling-group
    # depends on: LAUNCH_TEMPLATE_ID
    # output variable: ASG_ARN
    # quick link: https://panlm.github.io/CLI/functions/func-create-auto-scaling-group.sh
    
    function create-auto-scaling-group () {
        OPTIND=1
        OPTSTRING="h?l:"
        local LAUNCH_TEMPLATE_ID=""
        local NUM=""
        while getopts ${OPTSTRING} opt; do
            case "${opt}" in
                l) LAUNCH_TEMPLATE_ID=${OPTARG} 
                ;;
                n) NUM=${OPTARG} 
                ;;
                h|\?) 
                    echo "format: create-auto-scaling-group -l LAUNCH_TEMPLATE_ID [-n NUM]"
                    echo -e "\tsample: create-auto-scaling-group "
                    echo -e "\tsample: create-auto-scaling-group -l lt-xxx -n 2"
                    echo
                    return 0
                ;;
            esac
        done
        : ${LAUNCH_TEMPLATE_ID:?Missing -l}
        : ${NUM:=0}
    
        local TMP=$(mktemp --suffix .asg)
        # get sg id
        aws ec2 describe-launch-template-versions --launch-template-id ${LAUNCH_TEMPLATE_ID} --versions '$Latest' |tee ${TMP}.lt
        local VERSION_NUM=$(cat ${TMP}.lt |jq -r '.LaunchTemplateVersions[0].VersionNumber')
        local SG_IDS=($(cat ${TMP}.lt |jq -r '.LaunchTemplateVersions[0].LaunchTemplateData.SecurityGroupIds[]'))
        local VPC_IDS=($(aws ec2 describe-security-groups --group-ids ${SG_IDS[@]} |jq -r '.SecurityGroups[].VpcId'))
        if [[ ${#VPC_IDS[@]} -ne 1 ]]; then
            echo 'SG belongs to different VPC'
            return 9
        fi
    
        # get private subnets or public subnets
        local VPC_ID=${VPC_IDS[@]}
        local SUBNET_IDS=$(aws ec2 describe-subnets \
            --filter "Name=vpc-id,Values=${VPC_ID}" \
            --query 'Subnets[?MapPublicIpOnLaunch==`false`].SubnetId' \
            --output text)
    
        if [[ -z ${SUBNET_IDS} ]]; then
            local SUBNET_IDS=$(aws ec2 describe-subnets \
                --filter "Name=vpc-id,Values=${VPC_ID}" \
                --query 'Subnets[?MapPublicIpOnLaunch==`true`].SubnetId' \
                --output text)
        fi
    
        local SUBNET_STR=$(echo ${SUBNET_IDS} |xargs |tr ' ' ',')
    
        local ASG_NAME=autoscaling-$(TZ=CST-8 date +%Y%m%d-%H%M)
        envsubst >${TMP}.asg <<-EOF
    {
      "AutoScalingGroupName": "${ASG_NAME}",
      "MinSize": 0,
      "MaxSize": 10,
      "VPCZoneIdentifier": "${SUBNET_STR}",
      "NewInstancesProtectedFromScaleIn": true,
      "MixedInstancesPolicy":{
        "LaunchTemplate":{
          "LaunchTemplateSpecification":{
            "LaunchTemplateId": "${LAUNCH_TEMPLATE_ID}",
            "Version": "${VERSION_NUM}"
          },
          "Overrides":[{}]
        }
      }
    }
    EOF
    
        aws autoscaling create-auto-scaling-group \
            --cli-input-json file://${TMP}.asg 
        aws autoscaling describe-auto-scaling-groups \
            --auto-scaling-group-names ${ASG_NAME} |tee ${TMP}.asg.out
        ASG_ARN=$(cat ${TMP}.asg.out |jq -r '.AutoScalingGroups[0].AutoScalingGroupARN')
        echo "ASG_ARN="${ASG_ARN}
    } # funcend
    

    refer: func-create-auto-scaling-group

warmpool

  • create warmpool with scale in policy

    ASG_NAME="Example Auto Scaling Group"
    aws autoscaling put-warm-pool \
        --auto-scaling-group-name ${ASG_NAME} \
        --pool-state Stopped \
        --instance-reuse-policy '{"ReuseOnScaleIn": true}'
    

  • create warmpool with min size 4

    aws autoscaling put-warm-pool \
        --auto-scaling-group-name my-asg \
        --pool-state Stopped --min-size 4
    

refer: https://docs.aws.amazon.com/autoscaling/ec2/userguide/examples-warm-pools-aws-cli.html

lifecycle-hook-

  • need an autoscaling role to create hook

    UNIQ=$(TZ=EAT-8 date +%Y%m%d-%H%M%S)
    ASG_NAME=${ASG_ARN##*/}
    
    ROLE_NAME=autoscaling-notification-role-${UNIQ}
    cat >trust.json <<-EOF
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": "autoscaling.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    EOF
    
    aws iam create-role --role-name ${ROLE_NAME} \
        --assume-role-policy-document file://./trust.json |tee ${ROLE_NAME}.out
    aws iam attach-role-policy --role-name ${ROLE_NAME} \
        --policy-arn "arn:aws:iam::aws:policy/service-role/AutoScalingNotificationAccessRole"
    ROLE_ARN=$(cat ${ROLE_NAME}.out |jq -r '.Role.Arn')
    

  • create sns or sqs as target

    # for sns
    #TARGET_ARN=$(aws sns create-topic --name asg-sns-${UNIQ} --query 'TopicArn' --output text)
    
    # for sqs
    QUEUE_URL=$(aws sqs create-queue --queue-name asg-sqs-${UNIQ} --query 'QueueUrl' --output text)
    ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    TARGET_ARN=arn:aws:sqs:${AWS_DEFAULT_REGION}:${ACCOUNT_ID}:${QUEUE_URL##*/}
    

  • create hook

    aws autoscaling put-lifecycle-hook \
        --lifecycle-hook-name hook-${UNIQ} \
        --auto-scaling-group-name ${ASG_NAME} \
        --lifecycle-transition autoscaling:EC2_INSTANCE_LAUNCHING \
        --role-arn ${ROLE_ARN} \
        --notification-target-arn ${TARGET_ARN}
    

refer

right-click & open-in-new-tab:

git/git-mkdocs/CLI/awscli/ecs-cmd

refer update-launch-template-

right-click & open-in-new-tab:

git/git-mkdocs/CLI/awscli/ecs-cmd

refer update-asg-

launch-template-and-auto-scaling-group-

SECGRP_ID=sg-xxx
AMI_ID=ami-xxx

INSTANCE_NAME=instance-$(date +%Y%m%d%H%M)
KEY_NAME=awskey

LAUNCH_TEMPLATE_NAME=launchtemplate-$(date +%Y%m%d%H%M)
TMP=$(mktemp --suffix ${LAUNCH_TEMPLATE_NAME})
envsubst >${TMP} <<-EOF
{
  "InstanceType": "m5.large",
  "ImageId": "${AMI_ID}",
  "KeyName": "${KEY_NAME}",
  "BlockDeviceMappings": [
    {
      "DeviceName": "/dev/xvda",
      "Ebs": {
        "Iops": 3000,
        "VolumeSize": 80,
        "VolumeType": "gp3",
        "Throughput": 125
      }
    }
  ],
  "TagSpecifications": [
    {
      "ResourceType": "instance",
      "Tags": [
        {
          "Key": "Name",
          "Value": "${INSTANCE_NAME}"
        }
      ]
    },
    {
      "ResourceType": "volume",
      "Tags": [
        {
          "Key": "Name",
          "Value": "${INSTANCE_NAME}"
        }
      ]
    },
    {
      "ResourceType": "network-interface",
      "Tags": [
        {
          "Key": "Name",
          "Value": "${INSTANCE_NAME}"
        }
      ]
    }
  ],
  "SecurityGroupIds": [
    "${SECGRP_ID}"
  ],
  "MetadataOptions": {
    "HttpTokens": "optional",
    "HttpPutResponseHopLimit": 2
  }
}
EOF

aws ec2 create-launch-template \
  --launch-template-name ${LAUNCH_TEMPLATE_NAME} \
  --launch-template-data file://${TMP}

ASG_NAME=autoscaling-$(date +%Y%m%d%H%M)
SUBNET_ID=subnet-03c26cc2c8b2eda6e
envsubst > ${ASG_NAME}.json <<-EOF
{
  "AutoScalingGroupName": "${ASG_NAME}",
  "MinSize": 1,
  "MaxSize": 1,
  "VPCZoneIdentifier": "${SUBNET_ID}",
  "MixedInstancesPolicy":{
    "LaunchTemplate":{
      "LaunchTemplateSpecification":{
        "LaunchTemplateName": "${LAUNCH_TEMPLATE_NAME}"
      },
      "Overrides":[
        {
          "InstanceType":"m5.xlarge"
        }
      ]
    }
  }
}
EOF

aws autoscaling create-auto-scaling-group \
--cli-input-json file://${ASG_NAME}.json

export AWS_PAGER=""
ASG_ARN=$(aws autoscaling describe-auto-scaling-groups \
--auto-scaling-group-names ${ASG_NAME} \
--query 'AutoScalingGroups[0].AutoScalingGroupARN' \
--output text)

auto scaling

aws launchconfig
aws autoscaling delete-auto-scaling-group --auto-scaling-group-name AutoScalingGroup --force-delete