時間ベースのスケジュールに基づいてAWS EC2インスタンスを起動および停止する方法


17

毎日特定の時間にAWS EC2インスタンスを開始および停止する簡単な方法はありますか?これにより、開発サーバーとテストサーバーのコストを大幅に節約できます。

回答:


16

更新

AWSは、そのページからリンクされている完全な設定ガイドを含む「インスタンススケジューラ」と呼ばれるツールをリリースしました。これは、以下で説明するEC2スケジューラの拡張機能であり、さらにいくつかの機能を備えているように見えますが、基本的には同じものです。

以下のガイドでも引き続き機能しますが、おそらく新規インストールのインスタンススケジューラを確認する方が良いでしょう。

元の投稿

AWSにはEC2スケジューラと呼ばれるツールがあり、EC2インスタンスの起動と停止を非常に柔軟に制御できます。

このツールを使用すると、ツールのセットアップ時にデフォルトの開始時間と終了時間を定義できます。この時間は後で変更できます。どのインスタンスを制御するかを選択でき、タグを使用してインスタンスごとに異なる開始時間と停止時間を指定できます。

それは素晴らしいツールですが、ドキュメントはやや曖昧で分かりにくいです。ドキュメントは、テクニカルライターではなく、ツールを作成し、ツールに関するすべてを知っているエンジニアによって作成されたようなものです。

:フィードバックまたは修正がある場合は、コメントを歓迎します。これに基づいて質問がある場合は、独自の質問を開始してください。

EC2スケジューラとは

このツールは、Cloudwatch EventsおよびDynamoDBで動作するLambda関数です。Cloudformationテンプレートを使用してデプロイされ、必要なIAMロールとポリシーも設定されます。ここでアーキテクチャについて読むことができます

AWS EC2スケジューラアーキテクチャ

展開

このページに移動して、「ソリューションの起動」をクリックして開始します。現在、直接リンクはここにありますが、変更される可能性があります。

コンソールの上部で、リソースをデプロイするリージョンを選択します。スクリプトは任意のリージョンのEC2インスタンスを制御しますが、1つのリージョンで実行されます。

EC2インスタンスのタグ付け

これについては、こちらのドキュメントで説明していますが、それほど単純ではありません。

インスタンスにタグを付けることにより、どのインスタンスを開始および停止するかを制御します。

最も単純なケースでは、スケジュールに従って開始および停止する各EC2インスタンスにタグを付ける必要があります。これを行うには、コンソールでEC2インスタンスを見つけ、タグをクリックして、このタグを作成します

スケジューラーのEC2インスタンスのタグ付け

コピーと貼り付けを有効にするには:

  • キー:scheduler:ec2-startstop
  • 値:true

特定のインスタンスを別のスケジュールで開始および停止する場合は、タグのキーと値に追加情報を追加します。たとえば、火曜日、木曜日、金曜日にインスタンスを1500 UTCで開始し、2400 UTCで停止する場合、次のように入力します。

キー:scheduler:ec2-startstop:late値:1500; 2400; utc; tue、thu、fri

単語「late」には任意の文字列を指定できますが、「late」には特別な意味はありません。

このツールを使用して、UTCを現地時間に変換できます

タグエディタを使用して、タグインスタンスを一括処理できます。これにより、一括タグ付けをより簡単に設定できるようになります。これは、開発、テスト、および本番用に異なる設定を持つ場合に便利です。ただし、実稼働環境でこれを使用することはできません。

CloudFormationパラメーター

CloudFormationテンプレートを実行するとき、多くのパラメーターを入力する必要があります。ほとんどの場合、デフォルトのままにしておくことができます。最も重要なパラメーターの一部を次に示します

  • スタック名:好きな名前を付けてください。CloudFormationで呼ばれているものです。
  • カスタムタグ名:これは、EC2インスタンスに対して配置したタグの「キー」です。正当な理由がない限り、または複数のインストールが必要な場合を除き、デフォルト値のままにします。
  • デフォルトの開始/停止時間:インスタンスを開始および停止するデフォルトのUTC時間
  • DynamoDB:設定はDynamoDBに保存されます。テーブル名などを変更できます。DynamoDBの無料利用枠は期限切れにならないため、ほとんどの人が請求されることはほとんどありません。
  • (2番目の画面)権限-これは赤いニシンです。以下のセクションを参照してください。デフォルトのままにして、EC2スケジューラーをセットアップするときに管理者として実行します。
  • 通知オプション:SNS通知をセットアップして、機能していることを検証できると便利だと感じました。私はそれらを無効にする方法を見つけるのに時間を費やしていません。それを削除して、Cloudformationテンプレートを再実行して再インストールしました。

権限、ポリシー、および役割

CloudFormationテンプレートのPermissions / IAMロールセクションは赤いニシンです。つまり、ほとんど関係ありません。CloudFormationスクリプトの実行に使用されるロールのみを指定し、作成されたリソースやラムダ関数の実行時に使用されるロールに違いはありません。振り返ってみると、これは明らかですが、私が始めたとき、それは私には明らかではありませんでした。

IAM内に同じロールおよびインラインアクセス許可としてこのスクリプトを実行するロールが作成されます。Lambda関数は、スクリプトが作成する「ec2スケジューラーロール」を使用して実行されます。

誰にとっても役立つ場合に備えて、以下に私のポリシーを含めました。

CloudWatchイベントとメトリックス

Lambda関数のログを表示する場合は、Cloudwatch Eventsに移動します。ロギングは非常に良好です。メトリックもありますので、いつ実行するか、実行する時間などを確認できます。

追加

ラムダ関数のコードはGithubで入手できます。

ポリシー

これらは一般に必要ではありませんが、誰かのためのものである可能性があるため、それらを含めます。

IAMロールのポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeTags",
                "iam:CreateRole",
                "iam:GetRole",
                "iam:PassRole",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:DeleteRole",
                "dynamodb:*",
                "lambda:*",
                "SNS:Publish",
                "events:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "S3:GetObject",
            "Resource": [
                "arn:aws:s3:::solutions-us-west-2",
                "arn:aws:s3:::solutions-us-west-2/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:StartInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:123456789012:instance/i-0d112345Ab6789012"
            ]
        }
    ]
}

IAMロールの信頼ポリシー

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com",
          "cloudformation.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

「EC2スケジューラは、AWSインスタンススケジューラによって取って代わられました」 - Amazonが変更されたもの以来、持っている
マックスBarraclough

ありがとう、リンクを含むように答えを更新しました。完全な実装ガイドが付属しているため、完全な指示を提供する必要はないと思います。
ティム

1
彼らがいかに物事を複雑にするのが好きなのか信じられないほどです...
Mehdi

9

インスタンスを開始および停止したいだけの場合は、Lambdaサービスも利用する別の方法があります。特定のインスタンスIDを制御することを前提としています。カンマで区切られたIDを追加することにより、複数のインスタンスを制御できます。(例:「i-3453453」、「i-45656745」)。インスタンスのIDは、AWSコンソールの[インスタンス]セクションで確認できます。

Lambdaコンソールで

  1. AWS Lambdaコンソールを開き、[関数の作成]を選択します。
  2. 最初から作成者を選択します。
  3. 「StopEC2Instances」など、関数の名前を入力します。
  4. ランタイムには、Python 2.7を選択します
  5. [ロール]ドロップダウンメニューを展開し、[カスタムロールの作成]を選択します。これにより、ブラウザに新しいタブまたはウィンドウが開きます。
  6. [IAMロール]ドロップダウンメニューで、[新しいIAMロールの作成]を選択し、「lambda_start_stop_ec2」などのロール名を入力します。
  7. [ドキュメントの表示]、[編集]の順に選択し、ドキュメントを読むように求められたら[OK]を選択します。ポリシー内のすべてのテキストをこれに置き換えます。

以下のコード

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:Start*",
        "ec2:Stop*"
      ],
      "Resource": "*"
    }
  ]
}
  1. [許可]を選択してロールの作成を終了し、AWS Lambdaコンソールに戻ります。
  2. インスタンスを停止するには、関数コードエディターのすべてのテキストを次のように置き換えます。

以下のコード

import boto3
region = ' eu-west-1'
instances = ['i-0dd344443184503fa']

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.stop_instances(InstanceIds=instances)
    print 'stopped your instances: ' + str(instances)

リージョンとインスタンスの値を自分のものに置き換えることを忘れないでください。

  1. [ランタイム]ドロップダウンメニューから[Python2.7]を選択します。
  2. [基本設定]で、[タイムアウト]機能に10秒を入力します。
  3. 保存を選択します。
  4. すべての手順を繰り返して、インスタンスを起動する別の関数を作成しますが、次のPythonスクリプトを使用してすべてを起動します。

以下のコード

import boto3
region = 'eu-west-1'
instances = [' i-0dd344443184503fa']

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.start_instances(InstanceIds=instances)
    print 'started your instances: ' + str(instances)

機能をスケジュールする

ここでは、夜にLambda関数をトリガーするCloudWatchイベントを作成します

  1. Amazon CloudWatchコンソールを開きます。
  2. [イベント]を選択し、[ルールの作成]を選択します。
  3. [イベントソース]で[スケジュール]を選択します。
  4. インスタンスを停止するタイミングをLambdaに指示する時間間隔またはcron式を入力します。正しい構文の詳細については、ルールのスケジュール式構文を参照してください。

注:Cron式はUTCで評価されます。ご希望のタイムゾーンに合わせて式を調整してください。以下は、毎日08:00 GMT / UTCに関数を実行する例です。

0 08 * * ? *
  1. [ターゲットの追加]を選択し、Lambda関数を選択します。
  2. [関数]で、インスタンスを停止するLambda関数を選択します。
  3. 詳細設定を選択します。
  4. 指定されたフィールドに次の情報を入力します。[名前]に、「StopEC2Instances」などの意味のある名前を入力します。[説明]に、「EC2インスタンスを毎日夜間に停止する」などの意味のある説明を追加します。[状態]で[有効]を選択します。
  5. ルールの作成を選択します。

午前中にインスタンスを再起動するには、これらの手順を繰り返し、希望する開始時間を使用します。関数が失敗するたびにメールメッセージを送信する場合は、SNSトピックを設定し、Lmbda関数作成ウィンドウのデバッグでそのメッセージの送信を構成できます。

このすべてのソースはここで見つけることができます:AWSドキュメント


いったいどうやって、エディターでPythonコードを大丈夫に見えるようにすることができますか?
18年

ヘルプ「?」をクリックします マークダウン形式の使用に関する詳細をご覧ください。serverfault.com/editing-help
jscott

1
これは、フォーマットコードのバグです。異なる書式設定の間にプレーンテキストを挿入する必要があります。この場合は、コードブロックと番号付きブロックです。それが私が「下のコード」を入れる理由です-すべての場所で意味がありませんが、それは動作します。
ティム

@Tim明確にしてくれてありがとう。知らなかったよ。cron式のフォーマットも解決しました。再度、感謝します。
18年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.