Published on

pulumi aws native: CloudFormation 스키마 기반 AWS 프로바이더

Authors
  • avatar
    Name
    Indo Yoon
    Twitter

pulumi aws native는 AWS Cloud Control API와 CloudFormation 리소스 스키마를 그대로 코드로 옮긴 Pulumi 프로바이더입니다. 기존 aws 프로바이더가 Terraform AWS 프로바이더를 기반으로 동작하는 것과 달리, AWS가 공개하는 스키마를 따르기 때문에 리소스 타입 이름과 속성 이름, 태그 전달 방식이 눈에 띄게 다릅니다. 새로 나온 AWS 리소스를 빠르게 코드로 관리하고 싶다면 aws native를, 풍부한 예제와 편의 기능이 필요하다면 기존 aws 프로바이더를 고르는 것이 일반적인 판단 기준입니다.

한눈에 보기

pulumi aws native를 한 문장으로 줄이면 "AWS가 정의한 리소스 스키마를 그대로 노출하는 프로바이더"입니다. 그래서 코드의 모양이 Terraform 스타일이 아니라 CloudFormation 템플릿에 가깝습니다. CloudFormation을 이미 다뤄 본 백엔드 개발자라면 속성 이름이 낯익게 느껴질 가능성이 큽니다.

  • 기반 기술: AWS Cloud Control API와 CloudFormation 리소스 스키마
  • 패키지 이름: JavaScript·TypeScript는 @pulumi/aws-native, Python은 pulumi_aws_native, .NET은 Pulumi.AwsNative, Go는 aws-native 모듈을 사용합니다
  • 리소스 타입 표기: aws-native:s3:Bucket, aws-native:ec2:Vpc처럼 CloudFormation 타입 이름을 그대로 따릅니다
  • 속성 이름: CloudFormation 스키마에 정의된 이름을 사용합니다
  • 태그: 맵이 아니라 key와 value를 가진 객체의 배열로 전달합니다
  • 강점: AWS가 스키마를 공개하는 시점에 가깝게 리소스를 사용할 수 있습니다
  • 약점: 기존 aws 프로바이더에 있는 조회 함수와 커뮤니티 예제가 상대적으로 적습니다

두 프로바이더는 한 프로젝트 안에서 함께 사용할 수 있습니다. 다만 같은 리소스를 양쪽 프로바이더로 동시에 관리하면 상태가 충돌하므로, 리소스 단위로 소유권을 명확히 나누는 것이 안전합니다.

기존 aws 프로바이더와의 비교

가장 많이 헷갈리는 지점은 "이름만 다른 같은 물건"이 아니라는 사실입니다. 아래 표는 실무에서 체감 차이가 큰 항목만 정리한 것입니다.

항목aws (클래식)aws-native
코드 생성 기반Terraform AWS 프로바이더AWS CloudFormation 리소스 스키마
AWS 호출 경로각 서비스 API 직접 호출AWS Cloud Control API 경유
리소스 타입 표기aws:s3:Bucketaws-native:s3:Bucket
속성 이름Terraform 스키마 기준CloudFormation 속성 이름 기준
태그 전달 방식키와 값을 가진 맵key·value 객체의 배열
신규 리소스 반영프로바이더 릴리스 주기의 영향스키마 공개 시점에 가까움
편의 함수조회·유틸리티 함수가 다양함상대적으로 적음
기존 예제와 사례매우 많음계속 늘어나는 중
잘 맞는 상황안정적 운영, 풍부한 참고 자료최신 리소스, CloudFormation과의 정합성

이 차이는 실제 코드에서 바로 드러납니다. 태그를 맵으로 넘기면 타입 오류가 나고, AMI 조회처럼 기존 프로바이더에서 익숙했던 편의 함수가 없어서 직접 값을 지정해야 하는 경우도 생깁니다. 반대로 CloudFormation 템플릿을 이미 운영 중이라면 속성 이름이 거의 그대로 대응되어 이관이 수월해집니다.

단계별 도입 절차

aws native를 처음 붙이는 순서는 일반적인 Pulumi 프로젝트와 크게 다르지 않습니다. 차이는 패키지 이름과 리전 설정 키 정도입니다.

프로젝트와 패키지 준비

TypeScript 기준으로 프로젝트를 만들고 aws native 패키지를 추가합니다.

pulumi new typescript
npm install @pulumi/aws-native

기존 aws 프로바이더를 쓰던 프로젝트라면 패키지를 추가로 설치하고, 새 리소스만 aws native로 작성하는 방식으로 시작할 수 있습니다.

리전과 자격 증명 설정

리전은 프로바이더 설정으로 지정합니다. 아래 예시는 서울 리전을 사용하는 경우입니다.

pulumi config set aws-native:region ap-northeast-2

자격 증명은 AWS SDK가 사용하는 표준 방식을 그대로 따릅니다. CI/CD 파이프라인에서는 환경 변수나 역할 위임을 통해 주입하는 편이 관리하기 쉽습니다.

리소스 정의

aws native 리소스는 네임스페이스 아래에 서비스별로 묶여 있습니다. 버킷 하나를 만들어 보면 태그 형식이 기존과 다르다는 점이 바로 보입니다.

import * as pulumi from "@pulumi/pulumi";
import * as awsNative from "@pulumi/aws-native";

const logs = new awsNative.s3.Bucket("logs", {
  bucketName: "devbull-logs-example",
  tags: [
    { key: "team", value: "platform" },
    { key: "managed-by", value: "pulumi" },
  ],
});

export const bucketArn = logs.arn;

미리보기와 배포

리소스를 작성한 뒤에는 미리보기로 변경 사항을 확인하고 배포합니다.

pulumi preview
pulumi up

배포 결과는 스택 출력으로 확인할 수 있습니다. Cloud Control API를 경유하기 때문에 오류 메시지가 AWS 서비스의 원문에 가깝게 올라오는 경우가 많으니, 실패 시 메시지를 그대로 읽는 습관이 도움이 됩니다.

기존 리소스 가져오기

이미 손으로 만든 리소스를 코드로 편입하려면 import를 사용합니다. 식별자는 리소스 종류마다 다르며, 버킷이라면 버킷 이름을 그대로 씁니다.

pulumi import aws-native:s3:Bucket logs devbull-logs-example

가져오기 후에는 반드시 pulumi preview로 차이가 없는지 확인해야 합니다. 스키마 기반 프로바이더는 기본값 처리 방식이 달라서, 코드에 명시하지 않은 속성이 차이로 잡히는 경우가 있습니다.

상황별 선택 기준

어떤 프로바이더를 쓸지는 리소스 단위로 결정하는 편이 현실적입니다.

  • 새로 출시된 AWS 서비스를 바로 코드로 관리해야 한다면 aws native가 유리합니다. 스키마가 공개되면 비교적 빠르게 대응할 수 있기 때문입니다.
  • CloudFormation 템플릿이나 스택과 같은 정의를 유지해야 한다면 aws native가 자연스럽습니다. 속성 이름과 구조가 그대로 대응됩니다.
  • 기존에 aws 프로바이더로 운영 중인 스택이라면 굳이 전면 교체할 필요는 없습니다. 신규 리소스만 aws native로 추가하고 스택을 분리하는 방식이 안전합니다.
  • 커뮤니티 예제와 문서를 많이 참고해야 하는 초기 구축 단계라면 기존 aws 프로바이더가 여전히 편합니다.
  • CloudFormation 템플릿을 Pulumi 코드로 옮기는 작업이라면 변환 도구를 먼저 검토해 보시기 바랍니다. 변환 결과가 aws native 코드로 나오는 경우가 많습니다.

한 스택 안에서 두 프로바이더를 섞을 때는 리소스 소유권을 문서화해 두는 것이 좋습니다. 나중에 담당자가 바뀌면 어느 리소스가 어느 프로바이더 소관인지 찾기 어려워집니다.

주의할 점

도입 전에 반드시 확인해야 할 항목들을 정리했습니다.

  • 태그 형식: aws native는 태그를 key와 value 객체의 배열로 받습니다. 기존 코드의 맵 형태를 그대로 옮기면 타입 오류가 납니다.
  • 속성 이름: CloudFormation 스키마의 이름을 쓰기 때문에 기존 aws 프로바이더와 표기가 다릅니다. 리소스 문서를 열어 실제 필드 이름을 확인하는 편이 빠릅니다.
  • Cloud Control API 지원 범위: 모든 CloudFormation 리소스가 Cloud Control API에서 지원되는 것은 아닙니다. 사용하려는 리소스가 지원 대상인지 먼저 확인해야 합니다.
  • 이름 지정: 이름을 직접 지정해야 하는 리소스가 있고, 지정하지 않으면 AWS가 생성한 값이 붙는 리소스도 있습니다. 운영 환경에서는 이름을 명시하는 편이 추적에 유리합니다.
  • 교체 동작: 생성 시에만 지정할 수 있는 속성을 바꾸면 리소스가 교체될 수 있습니다. 데이터가 있는 리소스라면 미리보기에서 교체 여부를 반드시 확인하세요.
  • 호출 한도와 배포 시간: 리소스마다 Cloud Control API를 호출하므로 리소스가 많은 스택에서는 배포가 느려지거나 호출 한도에 걸릴 수 있습니다. 스택을 목적별로 나누면 완화됩니다.
  • 버전 고정: 프로바이더 버전을 올리면 스키마가 바뀌어 예상치 못한 차이가 생길 수 있습니다. 잠금 파일로 버전을 고정하고 업그레이드는 별도 작업으로 다루는 편이 안전합니다.
  • 상태 이관: 같은 리소스를 두 프로바이더로 관리하지 마세요. 이관이 필요하면 import나 상태 이동으로 소유권을 한쪽으로 모아야 합니다.

자주 묻는 질문

aws-native와 기존 aws 프로바이더를 한 프로젝트에서 같이 써도 되나요?

가능합니다. 두 패키지를 모두 설치하고 리소스마다 적절한 프로바이더를 선택하면 됩니다. 다만 같은 실제 리소스를 양쪽에서 관리하면 상태가 어긋나므로, 리소스 소유권을 명확히 나누고 문서로 남겨 두시기 바랍니다.

기존 aws 프로바이더로 만든 리소스를 aws-native로 옮길 수 있나요?

가능하지만 자동으로 되지는 않습니다. 기존 스택에서 리소스를 상태에서 제거하고, aws native 코드로 다시 정의한 뒤 import로 편입하는 절차를 거쳐야 합니다. 이관 중에는 다운타임이나 교체 위험이 있으므로 미리보기로 차이를 확인하는 과정이 필수입니다.

aws-native는 모든 AWS 리소스를 지원하나요?

그렇지 않습니다. aws native는 Cloud Control API가 지원하는 리소스를 대상으로 하므로, CloudFormation에는 있지만 Cloud Control API에서 다루지 않는 리소스는 사용할 수 없습니다. 필요한 리소스가 있다면 공식 문서의 지원 범위를 먼저 확인하고, 없으면 기존 aws 프로바이더를 함께 쓰는 방법을 검토하세요.

태그를 맵으로 넘겼더니 오류가 납니다.

aws native는 CloudFormation의 태그 구조를 그대로 따르기 때문에 key와 value를 가진 객체의 배열을 기대합니다. 기존 aws 프로바이더 코드를 그대로 복사했다면 이 부분을 배열 형태로 바꿔 주셔야 합니다.

배포가 갑자기 느려졌습니다.

리소스마다 Cloud Control API를 호출하는 구조이기 때문에 리소스 수가 늘어날수록 배포 시간이 길어질 수 있습니다. 스택을 역할별로 나누거나, 자주 바뀌지 않는 기반 리소스를 별도 스택으로 분리하면 체감 속도를 개선할 수 있습니다.

출처

배포 자동화와 상태 관리까지 함께 고민하고 있다면 Pulumi의 AWS 가이드와 프로바이더 개념 문서를 나란히 두고 보시길 권합니다. 파이프라인에서 리전과 자격 증명을 어떻게 주입할지, 스택을 어떤 단위로 나눌지는 결국 프로바이더 선택만큼 중요한 운영 결정이기 때문입니다. 관련 운영 글은 Pulumi AWS 가이드에서 이어서 확인하실 수 있습니다.