이전시간에서는 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’ 버튼을 클릭해 배포하세요.
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에 추가합니다.
{
"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 작업을 제출합니다. 이때 Job Queue Name은 ①번 단계에서 생성한 리소스 명칭으로 바꾸어 입력해 주세요
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 확장자로 저장한 뒤, 아래 화면의 Choose file을 클릭해 해당 파일을 선택하고 Product 생성(Create product) 을 진행합니다.


https://worldoverthecloud.tistory.com/25 에서 만든 Portfolio에 위에서 생성한 Product를 추가합니다.

5. AWS Service Catalog를 실행한다.
Products 메뉴로 이동하여 ‘Launch product’를 클릭합니다.

Launch 템플릿에서 CloudFormation 소스 코드에 선언된 Parameters 값을 확인할 수 있습니다
https://worldoverthecloud.tistory.com/25 에서 Job Definition, JobName, JobQueue 정보를 확인한 뒤, 해당 항목에 AWS Batch 관련 값을 입력하고 Launch를 클릭하세요.

6. Batch 실행 여부를 확인한다
AWS Batch에 들어가면 Job 실행 된 내역을 볼 수 있습니다.


지금까지 AWS Batch를 AWS Service Catalog로 표준화·자동화하는 방법을 살펴보았습니다.
위의 예시처럼, 프로젝트 진행 시 변경이 드물었던 컴퓨팅 환경(Compute Environment) 과 작업 대기열(Job queues) 은 Catalog로 생성하지 않고 콘솔에서 초기 1회 구성으로 마쳤습니다. 반면, 배치가 업데이트될 때마다 변경이 필요한 Job Definition 생성과 Job 실행(제출)처럼 지속적으로 적용이 필요한 부분은 Service Catalog로 구현했습니다.
프로젝트 업무 요건에 맞게 Service Catalog 구성을 조정하고, 템플릿을 최대한 효율적으로 설계해 운영 부담을 줄이시길 권장드립니다. 감사합니다.