how to stop and start AWS EC2 instance automatically

会有一股神秘感。 提交于 2021-02-07 20:41:40

问题


I'm a beginner in using AWS.

I just want to stop and start several EC2 instances automatically and periodically(Not reboot).

Is there any recommended way to do this?


回答1:


Amazon recently (Feb 2018) released the EC2 instance scheduler tool:

The AWS Instance Scheduler is a simple AWS-provided solution that enables customers to easily configure custom start and stop schedules for their Amazon Elastic Compute Cloud (Amazon EC2) and Amazon Relational Database Service (Amazon RDS) instances. The solution is easy to deploy and can help reduce operational costs for both development and production environments. Customers who use this solution to run instances during regular business hours can save up to 70% compared to running those instances 24 hours a day.

I had this up and running in my account in 15 minutes; very simple to use, and practically free.

https://aws.amazon.com/answers/infrastructure-management/instance-scheduler/




回答2:


AWS has a good doc explaining how you can achieve this using Lambda and Cloudwatch events. You can refer it - https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

This solution can be modified to get the EC2 list dynamically, or operate on a set of instances which can be identified based on a certain tag.




回答3:


Yes, you can do that using AWS Lambda. You can select the trigger in Cloudwatch which runs on Cron expressions on UTC.

Here is a related link https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

Another alternative is to use awscli which is available from pip, apt-get, yum or brew, and then running aws configure with your credentials from IAM and executing the following bash script, to stop an EC2 that has been tagged with Name: Appname and Value: Appname Prod. You can use awscli to tag your instances or tag it manually from the AWS console. aws ec2 stop-instances will stop the instance and jq is used to filter the json query and fetch the correct instance id using the tags from aws ec2 describe-instances.

To verify that aws configure was successful and returns json output run aws ec2 describe-instances and your running instance id should be there in the output. Here is a sample output

{
    "Reservations": [
        {
            "Instances": [
                {
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "PublicDnsName": "ec2-xxx.ap-south-1.compute.amazonaws.com",
                    "State": {
                        "Code": xx,
                        "Name": "running"
                    },
                    "EbsOptimized": false,
                    "LaunchTime": "20xx-xx-xxTxx:16:xx.000Z",
                    "PublicIpAddress": "xx.127.24.xxx",
                    "PrivateIpAddress": "xxx.31.3.xxx",
                    "ProductCodes": [],
                    "VpcId": "vpc-aaxxxxx",
                    "StateTransitionReason": "",
                    "InstanceId": "i-xxxxxxxx",
                    "ImageId": "ami-xxxxxxx",
                    "PrivateDnsName": "ip-xxxx.ap-south-1.compute.internal",
                    "KeyName": "node",
                    "SecurityGroups": [
                        {
                            "GroupName": "xxxxxx",
                            "GroupId": "sg-xxxx"
                        }
                    ],
                    "ClientToken": "",
                    "SubnetId": "subnet-xxxx",
                    "InstanceType": "t2.xxxxx",
                    "NetworkInterfaces": [
                        {
                            "Status": "in-use",
                            "MacAddress": "0x:xx:xx:xx:xx:xx",
                            "SourceDestCheck": true,
                            "VpcId": "vpc-xxxxxx",
                            "Description": "",
                            "NetworkInterfaceId": "eni-xxxx",
                            "PrivateIpAddresses": [
                                {
                                    "PrivateDnsName": "ip-xx.ap-south-1.compute.internal",
                                    "PrivateIpAddress": "xx.31.3.xxx",
                                    "Primary": true,
                                    "Association": {
                                        "PublicIp": "xx.127.24.xxx",
                                        "PublicDnsName": "ec2-xx.ap-south-1.compute.amazonaws.com",
                                        "IpOwnerId": "xxxxx"
                                    }
                                }
                            ],
                            "PrivateDnsName": "ip-xxx-31-3-xxx.ap-south-1.compute.internal",
                            "Attachment": {
                                "Status": "attached",
                                "DeviceIndex": 0,
                                "DeleteOnTermination": true,
                                "AttachmentId": "xxx",
                                "AttachTime": "20xx-xx-30Txx:16:xx.000Z"
                            },
                            "Groups": [
                                {
                                    "GroupName": "xxxx",
                                    "GroupId": "sg-xxxxx"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "OwnerId": "xxxx",
                            "PrivateIpAddress": "xx.xx.xx.xxx",
                            "SubnetId": "subnet-xx",
                            "Association": {
                                "PublicIp": "xx.xx.xx.xxx",
                                "PublicDnsName": "ec2-xx.ap-south-1.compute.amazonaws.com",
                                "IpOwnerId": "xxxx"
                            }
                        }
                    ],
                    "SourceDestCheck": true,
                    "Placement": {
                        "Tenancy": "default",
                        "GroupName": "",
                        "AvailabilityZone": "xx"
                    },
                    "Hypervisor": "xxx",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xxx",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": true,
                                "VolumeId": "vol-xxx",
                                "AttachTime": "20xxx-xx-xxTxx:16:xx.000Z"
                            }
                        }
                    ],
                    "Architecture": "x86_64",
                    "RootDeviceType": "ebs",
                    "RootDeviceName": "/dev/xxx",
                    "VirtualizationType": "xxx",
                    "Tags": [
                        {
                            "Value": "xxxx centxx",
                            "Key": "Name"
                        }
                    ],
                    "AmiLaunchIndex": 0
                }
            ],
            "ReservationId": "r-xxxx",
            "Groups": [],
            "OwnerId": "xxxxx"
        }
    ]
}

The following bash script is stop-ec2.sh in /home/centos/cron-scripts/

(instance=$(aws ec2 describe-instances | jq '.Reservations[].Instances | select(.[].Tags[].Value | startswith("Appname Prod") ) |  select(.[].Tags[].Key == "Appname") |  {InstanceId: .[].InstanceId, PublicDnsName: .[].PublicDnsName, State: .[].State, LaunchTime: .[].LaunchTime, Tags: .[].Tags}  | [.]' | jq -r .[].InstanceId) && aws ec2 stop-instances --instance-ids ${instance} )

Run the file using sh /home/centos/cron-scripts/stop-ec2.sh and verify that the EC2 instance gets stopped. To debug run aws ec2 describe-instances | jq '.Reservations[].Instances | select(.[].Tags[].Value | startswith("Appname Prod") ) | select(.[].Tags[].Key == "Appname") | {InstanceId: .[].InstanceId, PublicDnsName: .[].PublicDnsName, State: .[].State, LaunchTime: .[].LaunchTime, Tags: .[].Tags} | [.]' | jq -r .[].InstanceId and see that it returns the correct instance ID which has been tagged.

Then in crontab -e the following line can be added

30 14 * * * sh /home/centos/cron-scripts/stop-ec2.sh >> /tmp/stop

which will log the output to /tmp/stop. The 30 14 * * * is the UTC cron expression that you can check in https://crontab.guru/




回答4:


Lambda script to stop instance:

import json
import boto3

# Enter the region your instances are in. Include only the region without specifying Availability Zone; e.g., 'us-east-1'
region = 'us-east-1'

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)

    filter = [{'Name': 'tag:Name', 'Values': ['****-env']}]  //give instance name here in place of ****-env

    instances = ec2.describe_instances(Filters=filter)

    #ec2.stop_instances(InstanceIds=instances)


    stop_instance = instances.get('Reservations')[0].get('Instances')[0].get('InstanceId')
    stop_instances = []
    stop_instances.append(stop_instance)

    ec2.stop_instances(InstanceIds=stop_instances)

Lambda script to start instance:

import json
import boto3

# Enter the region your instances are in. Include only the region without specifying Availability Zone; e.g., 'us-east-1'
region = 'us-east-1'

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)

    filter = [{'Name': 'tag:Name', 'Values': ['****-env']}]

    instances = ec2.describe_instances(Filters=filter)

    #ec2.stop_instances(InstanceIds=instances)


    start_instance = instances.get('Reservations')[0].get('Instances')[0].get('InstanceId')
    start_instances = []
    start_instances.append(start_instance)

    ec2.start_instances(InstanceIds=start_instances)



回答5:


ASG scheduler is the best and easiest option to mange the EC2 instance if you are using ASG. If not using ASG, then you can use either AWS instance scheduler CF solution or lambda with cloudwatch Cron event.



来源:https://stackoverflow.com/questions/49147994/how-to-stop-and-start-aws-ec2-instance-automatically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!