Infrastructure as Code(IaC)는 인프라를 일관성 있고 반복 가능하게 관리해 오늘날 DevOps 환경에 널리 도입되고 있습니다. IaC를 사용해 인프라를 코드로 정의하면 변경 사항을 추적하고 롤백할 수 있고요. 환경을 쉽게 복제하며, 구성 오류도 줄일 수 있습니다. 이로써 인프라를 프로비저닝하고 관리하는 방식을 더 효율화할 수 있고요. 구성 드리프트, 운영자 실수, 정보 손실 등 문제도 해결할 수 있죠.
시중에는 Terraform, Pulumi, Nitric 등 다양한 IaC 도구가 있는데요. AWS의 CloudFormation(이하 CFN)도 유용한 IaC 도구입니다. CFN을 사용하면, 별도 상태 저장소를 설정하거나 유지할 필요가 없고요. AWS에서 CFN을 직접 개발했기에 AWS 서비스와 원활하게 통합할 수 있습니다. 또 DependsOn
속성을 사용해 명시적으로 의존성을 지정할 수 있고요.
업계를 둘러보면 AWS 클라우드에서 인프라를 관리하는 조직이 많은데요. 이러한 조직에서 CFN으로 IaC를 구축하면 위 장점을 누릴 수 있습니다. 이 글에서는 GitLab과 AWS의 CFN을 연동해 Lambda를 배포하는 방법을 알아보겠습니다.
AWS의 GitLab 접근 권한 설정
GitLab과 AWS의 CFN을 연동하려면, AWS에서 GitLab에 접근하도록 CodeConnections를 먼저 설정해야 합니다. 순서는 다음과 같습니다.
-
개발자 도구 > 설정 > 연결에서 연결 생성 버튼을 클릭합니다.
AWS 개발자 도구 설정 화면
-
연결 생성 > 공급자 선택에서 GitLab을 선택하고, GitLab 연결 생성에서 연결 이름을 입력합니다. 그다음, GitLab에 연결 버튼을 클릭하면 GitLab으로 리다이렉트됩니다.
AWS 개발자 도구 연결 생성 화면
-
아래 화면이 뜨면 Authorize 버튼을 클릭합니다.
AWS Connector for GitLab 권한 부여 관련 창
-
GitLab에 연결 > GitLab 연결 설정에서 연결 이름을 입력하고, 연결 버튼을 클릭합니다.
AWS 개발자 도구에서 GitLab 연결을 설정하는 화면
-
연결 설정 > 상태에 사용 가능이라고 뜨면, AWS에서 GitLab에 접근할 수 있습니다.
AWS에서 GitLab에 접근하도록 GitLab 연결 설정을 마무리한 결과
CFN 스택과 연동할 GitLab 프로젝트 생성
이어서 CFN 스택과 연동할 GitLab 프로젝트와 파일을 생성합니다. 순서는 다음과 같습니다.
-
GitLab 프로젝트를 생성합니다.
GitLab 프로젝트 생성 화면
-
배포 파일(deploy.yaml)과 템플릿 파일(lambda.yaml)을 프로젝트에 추가합니다.
-
배포 파일(또는 deployment file): CFN 스택을 관리하는 JSON 또는 YAML 형식의 파일입니다.
##예시 배포 파일
template-file-path: lambda.yaml
parameters: {}
tags: {}template-file-path
: CFN 템플릿 파일을 지정합니다.parameters
: 스택의 리소스를 구성하는 키-값 페어를 포함합니다.tags
: 스택의 리소스를 식별하고 분류하는 데 사용합니다.
-
템플릿 파일: CFN 스택을 구성할 AWS 리소스를 선언하는 JSON 또는 YAML 형식의 파일입니다.
##예시 템플릿 파일. Lambda를 생성합니다.
AWSTemplateFormatVersion: '2010-09-09'
Description: A CloudFormation template that creates a Lambda function.
Resources:
MyLambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action: ['sts:AssumeRole']
Policies:
- PolicyName: LambdaExecutionPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
MyLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt MyLambdaExecutionRole.Arn
Code:
ZipFile: |
import json
def handler(event, context):
print("hello from Lambda")
return {
'statusCode': 200,
'body': json.dumps('test')
}
Runtime: python3.8
Timeout: 30
-
Git Sync IAM Role, 정책 생성
이제 CFN이 Git 리포지터리에서 스택을 업데이트할 수 있는 Git Sync IAM Role과 정책을 생성합니다. CFN 스택을 생성할 때, 자동으로 해당 Role을 생성하는 옵션이 있습니다. 그러나 자동으로 Role을 생성하면 ‘CodeConnections에 접근 권한이 없다’는 에러가 발생합니다. 따라서 Role을 수동으로 생성해야 합니다. Git Sync IAM Role과 정책 생성 순서는 다음과 같습니다.
-
이 페이지에 접속해 Role을 생성합니다. 신뢰할 수 있는 엔터티 선택에서 신뢰할 수 있는 엔터티 유형으로 사용자 지정 신뢰 정책을 선택합니다.
AWS에서 Git Sync IAM Role을 생성하기 위해 신뢰할 수 있는 엔터티 유형을 선택하는 화면
아래는 사용자 지정 신뢰 정책 예시입니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CfnGitSyncTrustPolicy",
"Effect": "Allow",
"Principal": {
"Service": "cloudformation.sync.codeconnections.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
} -
생성한 Role을 선택해 권한을 추가합니다. CFN-IaC-role > 권한 > 권한 추가에서 인라인 정책 생성을 선택합니다.
AWS에서 생성한 Role의 권한을 추가하는 화면
-
권한 지정에서 JSON 편집기를 사용해 권한 설명문을 작성합니다.
AWS에서 JSON 편집기로 권한 설명문을 작성하는 화면
아래는 권한 설명문 예시입니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SyncToCloudFormation",
"Effect": "Allow",
"Action": [
"cloudformation:CreateChangeSet",
"cloudformation:DeleteChangeSet",
"cloudformation:DescribeChangeSet",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeStacks",
"cloudformation:ExecuteChangeSet",
"cloudformation:GetTemplate",
"cloudformation:ListChangeSets",
"cloudformation:ListStacks",
"cloudformation:ValidateTemplate"
],
"Resource": [
"arn:aws:cloudformation:ap-northeast-2:373015672791:stack/*"
]
},
{
"Sid": "PolicyForManagedRules",
"Effect": "Allow",
"Action": [
"events:PutRule",
"events:PutTargets"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"events:ManagedBy": [
"cloudformation.sync.codeconnections.amazonaws.com"
]
}
}
},
{
"Sid": "PolicyForDescribingRule",
"Effect": "Allow",
"Action": "events:DescribeRule",
"Resource": "*"
}
]
}JSON 설정에서 .Statement.Resource의 값인
arn:aws:cloudformation:ap-northeast-2:373015672791:stack/*
은 사용자가 이용하는 리전에 따라 변경될 수 있습니다.
CFN IAM Role 생성
그다음, 스택에서 수행되는 모든 작업에 사용할 CFN IAM Role을 생성합니다. 앞서 생성한 Git Sync IAM Role은 CFN에서 Git Sync 하는 Role이고요. CFN IAM Role은 Git Sync 이후 CFN 내 스택을 AWS의 실제 리소스 작업(describe, create, update, delete 등)에 사용하는 Role입니다. CFN IAM Role 생성 순서는 다음과 같습니다.
-
이 페이지에 접속해 Role을 생성합니다. 신 뢰할 수 있는 엔터티 선택에서 신뢰할 수 있는 엔터티 유형은 AWS 서비스를, 사용 사례는 CloudFormation을 각각 선택하고 다음 버튼을 클릭합니다.
AWS에서 CFN IAM Role을 생성하기 위해 신뢰할 수 있는 엔터티 유형과 사용 사례를 선택하는 화면
-
권한 추가 > 권한 정책에서 앞서 생성한 Role에 연결할 정책을 선택합니다.
AWS에서 생성한 Role에 연결할 정책을 선택하는 화면
-
이름 지정, 검토 및 생성 > 역할 세부 정보에서 역할 이름과 설명을 각각 입력한 다음, Role을 생성합니다.
AWS에서 Role의 역할 이름과 설명을 각각 입력하는 화면
CFN 스택 생성
이제 GitLab과 연동할 CFN 스택을 생성합니다. 순서는 다음과 같습니다.
-
AWS CFN 페이지에 접속해 스택 생성 버튼을 클릭합니다.
AWS에서 CFN 스택을 생성하는 화면
-
스택 생성 > 사전 조건 - 템플릿 준비에서 템플릿 준비는 기존 템플릿 선택을, 템플릿 지정에서 템플릿 소스는 Git에서 동기화하기 - 신규를 선택하고, 다음 버튼을 클릭합니다.
AWS에서 CFN 스택을 생성할 때 템플릿 준비, 템플릿 소스를 지정하는 화면
-
생성할 스택의 세부 정보를 설정합니다. 스택 세부 정보 지정에서 아래 항목을 각각 입력 또는 선택하고, 다음 버튼을 클릭합니다.
-
스택 이름: 스택 이름을 지정합니다.
-
배포 파일 생성: 스택 배포 파일을 제공하는 방법을 선택합니다.
-
템플릿 정의 리포지토리: Git 리포지터리와 동기화할 스택 템플릿의 리포지터리를 지정합니다.
-
리포지토리 공급자 선택: 리포지터리 공급업체를 선택합니다.
-
연결: 리포지터리와의 연결을 선택합니다. 기존 연결을 선택하거나 새 연결을 추가할 수 있습니다.
-
리포지토리: 템플릿을 포함하는 Git 리포지터리를 선택합니다.
-
브랜치: CFN이 템플릿을 동기화할 브랜치를 선택합니다.
-
배포 파일 경로: 템플릿의 배포 파일 경로를 지정합니다.
-
기존 IAM 역할: CFN이 Git 리포지터리에서 스택을 업데이트하는 데 필요한 IAM 역할입니다.
AWS에서 CFN 스택 세부 정보를 설정하는 화면
-
-
스택에서 수행되는 모든 작업에 사용할 CFN의 IAM Role을 설정합니다. 스택 옵션 구성 > 권한 - 선택 사항 > IAM 역할에서 앞서 생성한 CFN IAM Role을 선택합니다.
AWS에서 CFN의 IAM Role을 설정하는 화면
-
고급 옵션 > 다음 버튼을 누르고, 스택 생성 옵션 > 전송 버튼을 클릭해 스택 설정을 마무리합니다.
AWS에서 CFN 스택 설정을 마무리하는 화면-1
AWS에서 CFN 스택 설정을 마무리하는 화면-2
GitLab-CFN 스택 동기화, 리소스 생성 확인
Git Sync가 정상적으로 동작해 Lambda가 생성된 걸 다음 화면과 같이 확인할 수 있습니다.



GitLab에서 템플릿 파일 수정→Lambda 업데이트
마지막으로 GitLab에서 템플릿 파일을 수정한 다음, Lambda를 업데이트해 배포를 완료합니다. 순서는 다음과 같습니다.
-
먼저 GitLab 리포지터리에 있는 템플릿 파일인 lambda.yaml 내용을 아래 화면과 같이 수정합니다.
lambda.yaml 파일 내용 수정 사항
-
다음 화면에서 보듯 GitLab 파이프라인이 external로 동작합니다.
GitLab 파이프라인이 external로 동작하는 걸 보여주는 화면
-
해당 파이프라인을 클릭하면 AWS의 CFN 페이지로 이동해 아래 화면과 같이 진행 상황을 볼 수 있습니다.
AWS의 CFN 페이지에서 이벤트 진행 상황을 확인하는 화면
-
정상적으로 업데이트가 반영된 걸 Lambda에서 다음 화면과 같이 확인할 수 있습니다. 이로써 GitLab과 AWS의 CFN을 연동해 Lambda 배포를 완료했습니다.
Lambda 업데이트를 보여주는 화면