AWS BatchでPythonスクリプトを自動実行する処理をAWS CDKを使って、コードベースで書きます。
CDK・Batchの実行スクリプト共に言語は、Python
CDKドキュメントに記載されているPythonコード通りに書いても、デプロイ時にエラーが発生し、苦戦しました。
アーキテクチャ概要
サービスの役割
-
GitLab CI/CD
- アプリケーションコードをGitLabリポジトリにプッシュすると、CI/CDパイプラインがDockerイメージをビルド
- ビルドしたイメージをAmazon ECRにプッシュ
-
Amazon ECR (Elastic Container Registry)
- コンテナイメージを保存するAWSのDockerレジストリ
- イメージはAWS Batchで使用
-
AWS Batch
- スケーラブルなバッチ処理環境
- ジョブキューとコンピュート環境を使用してジョブを管理
-
AWS CDK (Cloud Development Kit)
- AWSリソースをコードで定義・管理
- BatchやEventBridgeの設定を自動化
-
Amazon EventBridge
- スケジュールルールでBatchジョブをトリガー
- ジョブを自動実行。(今回は、毎朝7時)
データフロー
-
GitLab CI/CD → Amazon ECR
- 開発者がコードをGitLabリポジトリにプッシュ
- GitLabの
.gitlab-ci.yml
で以下のプロセスを実行:- Dockerイメージのビルド
- AWS認証を行い、ビルドしたイメージをECRにプッシュ
-
Amazon ECR → AWS Batch
- AWS BatchがECRからコンテナイメージを取得
- ジョブ定義に基づき、コンピュートリソースを動的に割り当ててジョブを実行
-
Amazon EventBridge → AWS Batch
- EventBridgeのスケジュールルールを使用して、毎朝7時にBatchジョブをトリガー
- CRON式でスケジュールを柔軟に管理可能
-
ジョブ実行結果の確認
- ジョブ実行時のログはCloudWatch Logsに保存
- ジョブのステータス (成功/失敗) はAWS Management ConsoleまたはCloudWatchで確認
実装手順
- ECRリポジトリの作成
GitLab CI/CDがDockerイメージをプッシュするためのECRリポジトリを作成します。
以下は、AWS CDKを使用したリソース作成の例です。
from aws_cdk import aws_ecr as ecr
repository = ecr.Repository(
self, "dev-batch_app", #CloudFormationで割り当てられるリソース名
repository_name="dev-batch_app",
image_scan_on_push=True,
removal_policy=RemovalPolicy.DESTROY, #スタック削除時に削除する
empty_on_delete=True
)
-
GitLab CI/CD の設定
.gitlab-ci.yml
を使用して以下のパイプラインを作成します。
これにより、コードの変更時にDockerイメージをECRに自動プッシュします。
環境ごとにリポジトリを分けることを想定してます。
.gitlab-ci.yml
stages:
- deploy
- build
.batch_app-docker_build:
stage: build
image: docker:latest
script:
- docker build -t $ECR_REPOSITORY_NAME .
- aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin <your_account_id>.dkr.ecr.$AWS_REGION.amazonaws.com
- docker tag $ECR_REPOSITORY_NAME:latest <your_account_id>.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:latest
- docker push <your_account_id>.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:latest
dev-docker:
extends: .batch_app-docker_build
variables:
ECRRepositoryName: dev-batch_app
only:
- develop
- AWS CDKでAWSリソースの構築
from aws_cdk import
aws_batch as batch,
aws_events as events,
aws_events_targets as targets
# Fargate用Batch コンピューティング環境の作成
compute_environment = batch.ComputeEnvironment(
self, "devFargateComputeEnvironment", #CloudFormationで割り当てられるリソース名
compute_environment_name="FargateComputeEnvironment",
service_role=batch_service_role,
spot=False, #Fargate_spotをオフ
maxv_cpus=4,
vpc=vpc #VPC
)
# ジョブキューの作成
job_queue = batch.JobQueue(
self, "devJobQueue", #CloudFormationで割り当てられるリソース名
job_queue_name="devJobQueue",
priority=1,
compute_environment_order=[
batch.CfnJobQueue.ComputeEnvironmentOrderProperty(
compute_environment=compute_environment, #環境変数
order=1
)
]
)
# ジョブ定義の作成
job_definition = batch.CfnJobDefinition(
self, "devJobDefinition", #CloudFormationで割り当てられるリソース名
job_definition_name="devJobDefinition",
type="container",
retry_strategy={}, #ジョブ試行回数
platform_capabilities=["FARGATE"], #オーケストレーションタイプ
timeout=batch.CfnJobDefinition.TimeoutProperty(
attempt_duration_seconds=1800 #実行タイムアウト
),
container_properties=batch.CfnJobDefinition.ContainerPropertiesProperty(
image=repository.repository_uri, #ECRリポジトリURI
fargate_platform_configuration=batch.CfnJobDefinition.FargatePlatformConfigurationProperty(
platform_version="LATEST"
),
execution_role_arn=refresh_tri_dairy_batch_role.role_arn,
job_role_arn=refresh_tri_dairy_batch_role.role_arn,
resource_requirements=[
{'value': '1.0', 'type': 'VCPU'},
{'value': '2048', 'type': 'MEMORY'}
],
environment=environment_variables, #環境変数
network_configuration=batch.CfnJobDefinition.NetworkConfigurationProperty(
assign_public_ip="ENABLED"
),
runtime_platform=batch.CfnJobDefinition.RuntimePlatformProperty(
operating_system_family="LINUX",
cpu_architecture="X86_64"
)
)
)
job_definition.apply_removal_policy(policy=RemovalPolicy.DESTROY) #スタック削除時に削除する
# EventBridge ルールの作成
rule = events.Rule(
self,
'devEventBridgeRuleName', #CloudFormationで割り当てられるリソース名
rule_name="devEventBridgeRuleName",
schedule=events.Schedule.cron(minute='0', hour='22'), #毎日7時実行
targets=[targets.BatchJob(
job_queue.attr_job_queue_arn, #ジョブキューのARN
job_queue, #ジョブキュー定義
f"arn:aws:batch:{self.region}:{self.account}:job-definition/devEcrRepository", #ジョブ定義のARN
job_definition #ジョブ定義
)],
enabled=True
)
rule.apply_removal_policy(policy=RemovalPolicy.DESTROY) #スタック削除時に削除する