web-dev-qa-db-ja.com

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

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

17
Tim

更新

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

以下のガイドは引き続き機能しますが、新規インストールのインスタンススケジューラを確認することをお勧めします。

元の投稿

AWSには EC2スケジューラー というツールがあり、EC2インスタンスの開始と停止を非常に柔軟に制御できます。

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

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

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

EC2スケジューラとは

このツールは、CloudwatchイベントとDynamoDBで機能するLambda関数です。 Cloudformationテンプレートを使用してデプロイされます。これは、必要なIAMロールとポリシーもセットアップします。あなたはアーキテクチャについて読むことができます ここ

AWS EC2 Scheduler Architecture

導入

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

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

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

これはドキュメント here でカバーされていますが、それほど単純ではありません。

インスタンスにタグを付けることで、起動および停止するインスタンスを制御します。

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

EC2 Instance Tagging for Scheduler

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

  • キー: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 role]セクションは、赤いニシンです。つまり、ほとんど関係ありません。 CloudFormationスクリプトの実行に使用されるロールのみを指定します。作成されたリソースやラムダ関数の実行時に使用されるロールに違いはありません。振り返ってみると、これは明白ですが、私が始めたとき、私には明白ではありませんでした。

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

誰かに役立つ場合に備えて、以下のポリシーを記載しました。

CloudWatchイベントとメトリクス

Lambda関数からのログを表示する場合は、Cloudwatchイベントに移動します。ログはかなり良いです。メトリックもあるので、いつ実行されるか、いつ実行されるかなどを確認できます。

追加

ラムダ関数のコードは 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"
    }
  ]
}
16
Tim

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

Lambdaコンソールで

  1. AWS Lambdaコンソールを開き、[Create function]を選択します。
  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. [Add target]を選択してから、[Lambda function]を選択します。
  2. [関数]で、インスタンスを停止するLambda関数を選択します。
  3. 詳細の設定を選択します。
  4. 表示されたフィールドに次の情報を入力します。[名前]に、「StopEC2Instances」などのわかりやすい名前を入力します。 [説明]に、「EC2インスタンスを毎日夜に停止する」などの意味のある説明を追加します。 [状態]で、[有効]を選択します。
  5. [Create rule]を選択します。

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

このすべてのソースはここにあります: AWSドキュメント

10
netfed