이전시간에서는 AWS Catalog를 사용하여 AWS Batch를 실행하는 방법에 대하여 알아보았습니다.
이번편에서는 AWS Catalog를 사용하여 AWS Batch를 최종 실행하는 방법에 대하여 알아보도록 하겠습니다.
본 편을 실습하기 전에 아래 두 편을 순서대로 실습하신 뒤 진행하시길 권장합니다.
https://mcmp.cloudz.co.kr/blog/detail/237
https://mcmp.cloudz.co.kr/blog/detail/240
Batch 실행은 AWS Service Catalog 단독으로 실행하기 어려와 아래와 같이 최종 실행은 AWS Lamda가 실행하도록 구성하였습니다.
아래 그림의 실행 절차를 간단히 소개해드리면
1. Batch Job 정보를 가지고 Lamda를 실행하는 CloudFormation 코드를 만든다.
2. CloudFormatin 코드를 기반으로 AWS Catalog 를 생성한다.
3. AWS Catalog 를 실행한다.
4. Batch 실행이 되었는지 확인다.
이전 시간에는 AWS Service Catalog를 사용하여 AWS Batch Job Definion을 생성하는 방법에 대해서 알아보았습니다.
이번 편에서는 AWS Service Catalog를 사용하여 AWS Batch를 최종 실행하는 방법을 살펴보겠습니다.
Batch 실행은 Service Catalog만으로는 실행 트리거 구성이 어려워, 최종 실행은 AWS Lambda가 수행하도록 구성했습니다.
실행 절차는 다음과 같습니다.
- Console로 작업대기열 (Jobe queues), 컴퓨팅 환경 (Cpmpute Environmnet) 를 콘솔로 구성한다.
- Batch를 실행하는 Lambda를 구성한다.
- Batch Job 정보를 가지고 Lambda를 실행하는 CloudFormation 코드를 만든다.
- 위 CloudFormation 코드를 기반으로 AWS Service Catalog를 생성한다.
- AWS Service Catalog를 실행한다.
- Batch 실행 여부를 확인한다

1. Console로 작업대기열 (Jobe queues), 컴퓨팅 환경 (Environmnet) 를 콘솔로 구성한다.
필자가 수행한 프로젝트의 경우 작업 대기열(Job queues) 과 컴퓨팅 환경(Compute environments) 은 초기 구성 이후 변경이 거의 없었습니다. 이에 따라 AWS 콘솔에서 초기 설정만 진행했고, 이후에는 별도의 수정을 하지 않았습니다.자세한 구성 방법은 다음 글을 참고해 주시기 바라며, 해당 내용을 모두 완료하신 뒤 본 편을 진행하실 것을 권장드립니다.
https://mcmp.cloudz.co.kr/blog/detail/237
https://mcmp.cloudz.co.kr/blog/detail/240
2. Batch를 실행하는 Lambda를 구성한다.
Runtime을 Python으로 선택하고 Lambda를 생성합니다.
아래 파이썬 코드는 AWS Batch 실행을 위한 예제입니다. 두 번째 그림의 코드 에디터에 아래 코드를 붙여넣은 뒤 ‘Deploy’ 버튼을 클릭해 배포하세요.
아래 코드를 간단히 설명하면 Service Catalog Product를 프로비저닝(생성) 또는 업데이트하면 해당 상품이 생성한 CloudFormation 스택의 Custom Resource가 실행되고, 이때 lambda_handler가 트리거됩니다.
Lambda는 boto3의 Batch submit_job API를 호출하며, Service Catalog에서 사용자가 입력한 JobName, JobQueue, JobDefinition 값을 받아 AWS Batch 잡을 제출하도록 구성되어 있습니다.
lambda_function.py
from __future__ import print_function
import json
import urllib.request
# (추가) 로깅 사용 권장
import logging, boto3
log = logging.getLogger()
log.setLevel(logging.INFO)
SUCCESS = "SUCCESS"
FAILED = "FAILED"
def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False, reason=None):
responseUrl = event['ResponseURL']
log.info("CFN response URL: %s", responseUrl)
responseBody = {
'Status': responseStatus,
'Reason': reason or f'See the details in CloudWatch Log Stream: {context.log_stream_name}',
'PhysicalResourceId': physicalResourceId or context.log_stream_name,
'StackId': event['StackId'],
'RequestId': event['RequestId'],
'LogicalResourceId': event['LogicalResourceId'],
'NoEcho': noEcho,
'Data': responseData
}
json_responseBody = json.dumps(responseBody)
log.info("Response body: %s", json_responseBody)
headers = {
'content-type': '',
'content-length': str(len(json_responseBody))
}
try:
req = urllib.request.Request(responseUrl, data=json_responseBody.encode('utf-8'), headers=headers, method='PUT')
with urllib.request.urlopen(req) as response:
log.info("CFN PUT status=%s body=%s", response.getcode(), response.read().decode('utf-8'))
except Exception as e:
log.exception("send(..) failed executing urlopen(..): %s", str(e))
def lambda_handler(event, context):
log.info("RequestType=%s, LogicalId=%s", event.get("RequestType"), event.get("LogicalResourceId"))
log.info("ResourceProperties=%s", event.get("ResourceProperties"))
try:
if event["RequestType"] == "Delete":
send(event, context, SUCCESS, {"Message": "Delete no-op"})
return
props = event["ResourceProperties"]
batch = boto3.client("batch")
resp = batch.submit_job(
jobName=props["JobName"],
jobQueue=props["JobQueue"],
jobDefinition=props["JobDefinition"]
)
log.info(" SubmitJob resp=%s", resp)
send(event, context, SUCCESS, {"JobId": resp["jobId"]}, physicalResourceId=resp["jobId"])
except Exception as e:
log.exception("Handler error")
send(event, context, FAILED, {}, reason=str(e))

AWS Batch를 실행하려면 해당 Lambda에 필요한 권한이 있어야 합니다. 먼저 관련 IAM 정책(Policy) 을 생성한 뒤, Lambda에 연결된 IAM 역할(Role) 에 정책을 추가하세요. 아래 빨간색 박스로 표시된 역할(Role) 을 클릭합니다.
해당 Role을 클릭하고 아래 작성한 내용으로 Policy를 생성하여(lambda-batch-summit-policy) Role에 추가합니다.
아래 Policy에 대하여 간단히 설명하면 AWS Batch를 실행 (submitJob) 한다는 뜻입니다. 해당 권한이 있어야 Lambda가 Batch를 실행할 수 있습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "batch:SubmitJob",
"Resource": "*"
}
]
}

3. Batch Job 정보를 가지고 Lambda를 실행하는 CloudFormation 코드를 만든다.
아래 CloudFormation 템플릿은 Job Name, Job Queue Name, Job Definition Name을 기반으로 Lambda를 호출하여 AWS Batch 작업을 제출합니다. 이때 Parameters 섹션에 있는 Job Queue Name은 ①번 단계에서 생성한 리소스 명칭으로 바꾸어 입력해 주세요. Job Queue Name은 해당 프로젝트에서 변경될 가능성이 낮아 기본값(Default)으로 실제 리소스 값을 입력했습니다. 반면 Job Name과 Job Definition Name은 상대적으로 변경이 빈번하여 기본값에 실제 리소스 ARN을 넣지 않고 (Required) 표기를 사용해, 카탈로그 사용자가 직접 값을 입력하도록 유도했습니다.
Resources 섹션의 Custom::SubmitBatchJob에서 ServiceToken에 앞서 구성한 Lambda 함수 ARN을 지정했습니다. Service Catalog에서 Product를 Launch하면 이 템플릿으로 CloudFormation 스택이 생성되고, 커스텀 리소스가 만들어지면서 해당 Lambda가 호출됩니다. 해당 밑에서 살펴볼 Service Catalog 에서 Product Launch 시 해당 파라미터( JobName, JobQueue, JobDefinition )의 입력 값을 해당 Lambda에게 이벤트 발생 시 전달하도록 구성하였습니다.
AWSTemplateFormatVersion: '2010-09-09'
Description: Trigger existing Lambda (AWS-Batch-Job-Execute) to run a Batch job
Parameters:
JobName:
Type: String
Description: AWS Batch Job Name
Default: "JobName: (Required)"
JobQueue:
Type: String
Description: AWS Batch Job Queue Name
Default: "arn:aws:batch:us-east-1:3xxxxxxx275:job-queue/waf-job-queue"
JobDefinition:
Type: String
Description: AWS Batch Job Definition ARN
Default: "JobDefinitionName: (Required) ex: arn:aws:batch:ap-northeast-2:3xxxxxxx275:job-definition/waf-job-def-v05:1"
Resources:
TriggerBatchJob:
Type: Custom::SubmitBatchJob
Properties:
ServiceToken: arn:aws:lambda:us-east-1:3xxxxxxx275:function:AwsBatchJobExecute
JobName: !Ref JobName
JobQueue: !Ref JobQueue
JobDefinition: !Ref JobDefinition
4. 위 CloudFormation 코드를 기반으로 AWS Service Catalog를 생성한다.
위에서 작성한 소스코드를 .yaml 확장자로 저장합니다.
우리는 CloudFormation Template 을 사용하여 Product를 생성하기 때문에 첫번째 그림 처럼 Product type을 CloudFormation으로 선택하고
두번째 그림에 빨간색 박스에 표시된 Choose file을 클릭해 해당 파일을 선택하고 Product 생성(Create product) 을 진행합니다.

https://worldoverthecloud.tistory.com/25 에서 만든 Portfolio에 위에서 생성한 Product를 추가합니다.
5. AWS Service Catalog를 실행한다.
이제 AWS Service Catalog를 통하여 AWS Batch를 최종 실행하기 위한 모든 준비가 끝났습니다.
Products 메뉴로 이동하여 ‘Launch product’를 클릭합니다.
Launch 템플릿에서 CloudFormation 소스 코드에 선언된 Parameters 값을 확인할 수 있습니다
https://worldoverthecloud.tistory.com/25 에서 Job Definition, JobName, JobQueue 정보를 확인한 뒤, 해당 항목에 AWS Batch 관련 값을 입력하고 Launch를 클릭하세요.
6. Batch 실행 여부를 확인한다
AWS Batch에 들어가면 Job 실행 된 내역을 볼 수 있습니다.
두번째 그림처럼 AWS Calalog를 사용하여 SpringBoot Batch를 실행이 완료된 것을 로그를 통하여 볼 수 있습니다.
지금까지 AWS Batch를 AWS Service Catalog로 표준화·자동화하는 방법을 살펴보았습니다.
위의 예시처럼, 프로젝트 진행 시 변경이 드물었던 컴퓨팅 환경(Compute Environment) 과 작업 대기열(Job queues) 은 Catalog로 생성하지 않고 콘솔에서 초기 1회 구성으로 마쳤습니다. 반면, 배치가 업데이트될 때마다 변경이 필요한 Job Definition 생성과 Job 실행(제출)처럼 지속적으로 적용이 필요한 부분은 Service Catalog로 구현했습니다.
물론 상대적으로 복잡하고 표준화가 필요한 Job Definition만 Service Catalog로 구성할 수도 있습니다. 그럼에도 비교적 단순한 AWS Batch 실행까지 Catalog에 포함한 이유는, Batch 사용자에게 별도의 Batch 구성 권한을 부여하지 않고도 AWS Service Catalog를 통해 최소 권한만으로 핸즈온(Hands-on)을 진행할 수 있게 하기 위함입니다.
프로젝트 업무 요건에 맞게 Service Catalog 구성을 조정하고, 템플릿을 최대한 효율적으로 설계해 운영 부담을 줄이시길 권장드립니다.
이번편을 마지막으로 AWS Batch 관련 된 내용은 마치도록 하겠습니다.
감사합니다.
