
目次
はじめに
あるアプリケーションでLambdaをEventBridge Schedulerで5分おきに実行させるような構成を取っていました。
これをアプリケーションからEventBridge Scheduler APIを呼び出してスケジュールを動的に作成するようにできないかと考えました。
そこでまずはコンソールアプリで実際にSchedulerが作成できるかを検証したいと思います。
前提条件
今回実際にSchedulerで動かすのは既に作成済みのLambdaになります。
この時点で、IAMの用意も完了しているところからスタートになります。
コンソールアプリを作成
ターミナル上で下記を実行し、コンソールアプリを作成します。
> dotnet new console -n AWSSchedulerTest
コンソールアプリが作成できたら一応、実行します。
> dotnet run
Hello, World!
問題なさそうです。
初期のコードは消して検証していきます。
APIを呼び出す
パッケージをインストール
まずは必要なパッケージをインストールします。
> dotnet add package AWSSDK.Scheduler
> dotnet add package AWSSDK.SSOOIDC
> dotnet add package AWSSDK.SSO
インストールできたらProgram.csで読み込みましょう。
using Amazon.Scheduler;
using Amazon.Scheduler.Model;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
SSOプロファイルを使って対象アカウントにログインします。
var chain = new CredentialProfileStoreChain();
if (!chain.TryGetAWSCredentials("your-profile-name", out var credentials) || credentials is null)
{
Console.WriteLine("Error: AWS profile 'your-profile-name' could not be loaded. Run 'aws sso login --profile your-profile-name' first.");
return;
}
クライアントにSSOで取得したクレデンシャルを渡し、東京リージョンを指定します。
var client = new AmazonSchedulerClient(credentials, Amazon.RegionEndpoint.APNortheast1);
スケジューラ名とスケジューラの作成時間を定義します。
スケジューラ名は一意である必要があるので、いくつも作成する場合は後ろにGUIDなどをつけてください。
ScheduleExpression に渡す時刻はJSTとして解釈されます。 しかし DateTime.UtcNow はUTC時刻を返すため、そのまま渡すと 実際より9時間前の時刻として扱われ、スケジューラが即時実行されてしまいます。
そのため AddHours(9) でUTC→JST変換を行い、JSTの5分後を指定しています。
// 現在時刻の5分後にスケジュール作成(JST基準)
var startTime = DateTimeOffset.UtcNow.AddHours(9).AddMinutes(5);
// スケジュール名
var scheduleName = "scheduler-test";
try catch内にAPIを呼び出すコードを書きます。
try{
var response = await client.CreateScheduleAsync(new CreateScheduleRequest
{
// スケジュールの名前(同名は作成不可のためユニークな値を指定)
Name = scheduleName,
// 実行時刻の指定 at(...)形式で1回だけ実行するワンタイムスケジュールを作成
// yyyy-MM-ddTHH:mm:ss形式のUTC時刻を渡す
ScheduleExpression = $"at({startTime:yyyy-MM-ddTHH:mm:ss})",
// ScheduleExpressionで指定した時刻のタイムゾーン
// Asia/Tokyoを指定することでJSTとして解釈される
ScheduleExpressionTimezone = "Asia/Tokyo",
// スケジュール実行後の動作 DELETEを指定することで実行後に自動削除される
// ワンタイムスケジュールは実行後不要になるため削除しておくと管理が楽になる
ActionAfterCompletion = ActionAfterCompletion.DELETE,
// 実行時間のずれをどこまで許容するかの設定
// OFFにすることで指定時刻ちょうどに実行される(柔軟な時間枠を使わない)
FlexibleTimeWindow = new FlexibleTimeWindow
{
Mode = FlexibleTimeWindowMode.OFF
},
// スケジュール実行時に呼び出すターゲットの設定
Target = new Target
{
// 呼び出すLambda関数のARN
Arn = "arn:aws:lambda:ap-northeast-1:12345678912:function:your-lambda-name",
// EventBridge SchedulerがLambdaを呼び出す際に使用するIAMロールのARN
RoleArn = "arn:aws:iam::12345678912:role/your-scheduler-role",
// Lambda関数に渡すペイロード(JSON形式)
// Lambda側でeventとして受け取ることができる
Input = "{\"key\": \"value\"}"
}
});
Console.WriteLine($"作成成功: {response.ScheduleArn}");
}catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
最後に下記が全体のソースコードです。
using Amazon.Scheduler;
using Amazon.Scheduler.Model;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
var chain = new CredentialProfileStoreChain();
if (!chain.TryGetAWSCredentials("your-profile-name", out var credentials) || credentials is null)
{
Console.WriteLine("Error: AWS profile 'your-profile-name' could not be loaded. Run 'aws sso login --profile your-profile-name' first.");
return;
}
var client = new AmazonSchedulerClient(credentials, Amazon.RegionEndpoint.APNortheast1);
// 検証用: 現在時刻の5分後にスケジュール作成(JST基準)
var startTime = DateTimeOffset.UtcNow.AddHours(9).AddMinutes(5);
// var scheduleName = $"test-grant-{Guid.NewGuid():N}";
var scheduleName = "scheduler-test";
try
{
var response = await client.CreateScheduleAsync(new CreateScheduleRequest
{
// スケジュールの名前(同名は作成不可のためユニークな値を指定)
Name = scheduleName,
// 実行時刻の指定 at(...)形式で1回だけ実行するワンタイムスケジュールを作成
// yyyy-MM-ddTHH:mm:ss形式のUTC時刻を渡す
ScheduleExpression = $"at({startTime:yyyy-MM-ddTHH:mm:ss})",
// ScheduleExpressionで指定した時刻のタイムゾーン
// Asia/Tokyoを指定することでJSTとして解釈される
ScheduleExpressionTimezone = "Asia/Tokyo",
// スケジュール実行後の動作 DELETEを指定することで実行後に自動削除される
// ワンタイムスケジュールは実行後不要になるため削除しておくと管理が楽になる
ActionAfterCompletion = ActionAfterCompletion.DELETE,
// 実行時間のずれをどこまで許容するかの設定
// OFFにすることで指定時刻ちょうどに実行される(柔軟な時間枠を使わない)
FlexibleTimeWindow = new FlexibleTimeWindow
{
Mode = FlexibleTimeWindowMode.OFF
},
// スケジュール実行時に呼び出すターゲットの設定
Target = new Target
{
// 呼び出すLambda関数のARN
Arn = "arn:aws:lambda:ap-northeast-1:12345678912:function:your-lambda-name",
// EventBridge SchedulerがLambdaを呼び出す際に使用するIAMロールのARN
RoleArn = "arn:aws:iam::12345678912:role/your-scheduler-role",
// Lambda関数に渡すペイロード(JSON形式)
// Lambda側でeventとして受け取ることができる
Input = "{\"key\": \"value\"}"
}
});
Console.WriteLine($"作成成功: {response.ScheduleArn}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
プログラムを実行する
aws sso login --profile your-profile-name
プログラムを実行します。
> dotnet run
作成成功: arn:aws:scheduler:ap-northeast-1:12345678912:schedule/default/scheduler-test
実行が成功したので、マネジメントコンソールでSchedulerが作成されたか確認します。


無事に作成できていました。
実行時間も作成から5分後になってます。
まとめ
パッケージをインストールして、APIにパラメータを渡すだけで簡単にスケジューラを作成することができました。
この記事が皆さまのお役に立てれば嬉しいです。


