AWS EventBridge Scheduler:スケジュールに沿ってEC2を起動・停止する
Lambdaを介さずEventBridge SchedulerがEC2 APIを直接呼び出すことで、cronスケジュールに従ってEC2インスタンスを起動・停止します。
EventBridge Schedulerを使えば、間にLambda関数を挟むことなく、cronスケジュールに従ってEC2インスタンスを起動・停止できます。
構築
テスト用にEC2インスタンスを起動します。
aws ec2 run-instances \ --image-id ami-0f9fe1d9214628296 \ --count 1 \ --instance-type t2.micro \ --security-group-ids <SECURITY_GROUP_IDS> \ --subnet-id <SUBNET_ID>11〜16行目のScheduleStartExpressionとScheduleStopExpressionパラメータで、cron式を使ってスケジュールを定義します。
AWSTemplateFormatVersion: '2010-09-09'Description: EC2 scheduler
Parameters: Prefix: Type: String Default: ec2-scheduler InstanceIds: Type: String Description: '"i-1234567890abcdefg", "..."' ScheduleStartExpression: Type: String Default: 'cron(0 7 * * ? *)' ScheduleStopExpression: Type: String Default: 'cron(0 22 * * ? *)' ScheduleTimezone: Type: String Description: IANA timezone identifier. For the full list, refer to https://en.wikipedia.org/wiki/List_of_tz_database_time_zones Default: UTC AllowedValues: - UTC - Japan
Resources: ScheduleStart: Type: AWS::Scheduler::Schedule Properties: Name: !Sub ${Prefix}-schedule-start ScheduleExpression: !Ref ScheduleStartExpression ScheduleExpressionTimezone: !Ref ScheduleTimezone FlexibleTimeWindow: Mode: 'OFF' State: ENABLED Target: Arn: arn:aws:scheduler:::aws-sdk:ec2:startInstances Input: !Sub |- { "InstanceIds": [${InstanceIds}] } RoleArn: !GetAtt Role.Arn
ScheduleStop: Type: AWS::Scheduler::Schedule Properties: Name: !Sub ${Prefix}-schedule-stop ScheduleExpression: !Ref ScheduleStopExpression ScheduleExpressionTimezone: !Ref ScheduleTimezone FlexibleTimeWindow: Mode: 'OFF' State: ENABLED Target: Arn: arn:aws:scheduler:::aws-sdk:ec2:stopInstances Input: !Sub |- { "InstanceIds": [${InstanceIds}] } RoleArn: !GetAtt Role.Arn
Role: Type: AWS::IAM::Role Properties: RoleName: !Sub ${Prefix}-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - scheduler.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: ec2 PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - ec2:StartInstances - ec2:StopInstances Resource: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/i-*次のコマンドでCloudFormationスタックをデプロイします。
aws cloudformation deploy \ --template-file ./template.yaml \ --stack-name ec2-scheduler \ --parameter-overrides InstanceIds='"<INSTANCE_ID1>", "<INSTANCE_ID2>"' \ --capabilities CAPABILITY_NAMED_IAMテスト
プロビジョニングされたEventBridge Schedulerは、午前7時にEC2インスタンスを自動的に起動し、午後10時に停止します。
クリーンアップ
次のコマンドで、この例でプロビジョニングしたすべてのAWSリソースをクリーンアップします。
aws ec2 terminate-instances --instance-ids <INSTANCE_IDS>aws cloudformation delete-stack --stack-name ec2-schedulerまとめ
cron式を使った2つのEventBridge Scheduleを設定したことで、EC2インスタンスが午前7時に起動し、午後10時に自動的に停止するようになりました。この構成にLambda関数が一切登場しないのは、arn:aws:scheduler:::aws-sdk:ec2:startInstancesによってEC2 APIを直接ターゲットにしているためです。EventBridge SchedulerはAWS SDKを直接呼び出せるため、スケジュールとec2:StartInstances/ec2:StopInstancesを許可するIAMロールだけで解決策が完結します。コスト削減のためにこの仕組みに頼る前に確認しておくべき設定はScheduleExpressionTimezoneです。テンプレートではデフォルトがUTCになっているため、他のタイムゾーンの営業時間に合わせたいスケジュールでは明示的にこのパラメータを設定しないと、想定より数時間ずれてインスタンスが起動・停止してしまいます。
Related posts
Cognito User PoolsとOIDCでSlackサインインを実装する
Cognito user poolをOIDC経由でSlackと連携させ、"Sign in with Slack"をAmplifyでNext.jsアプリに組み込みます。
Lambda Web AdapterでFastAPIをAWS Lambdaにデプロイする
Lambda Web Adapterを使うと、FastAPIで書いたAPIバックエンドをコンテナのまま単一のLambda関数にデプロイできます。
API Gateway WebSocket:モック統合の実装
バックエンドのLambdaを一切使わず、モック統合のみでAPI Gateway WebSocket APIを構築し、あらかじめ用意されたレスポンスを返します。
CloudFront署名付きURL経由でS3にアップロードする
CloudFrontの署名付きURLを使えば、独自ドメイン経由でS3にアップロードできます。S3の直接の署名付きURLが使えない場合に有用です。
AWSにおけるモノリスからマイクロサービスへ:3つの移行パターン
『Monolith to Microservices』に触発され、AWSにおけるモノリスからマイクロサービスへの移行パターンを解説します。
