새소식

IaC/Pulumi

[Pulumi]Quick Start with AWS

  • -

개요

Pulumi는 클라우드 리소스를 관리하기 위한 인프라스트럭처 코드(IaC) 툴입니다. AWS, Azure, Google Cloud Platform 등 다양한 클라우드 제공업체를 지원합니다. 이 글에서는 macOS에서 Pulumi를 설치하고 이를 사용하여 AWS에 리소스를 배포하는 방법을 설명합니다.

Install pulumi on macOS

Homebrew Package Manager

brew install pulumi/tap/pulumi

Verify installation

➜ pulumi version
v3.105.0

Install Pulumi ESC

Pulumi ESC는 Pulumi의 확장 기능 중 하나로, 특정 클라우드 서비스에 대한 추가 지원을 제공합니다. ESC를 설치하려면, 먼저 Homebrew를 최신 상태로 업데이트한 후 ESC를 설치합니다.

brew update && brew install pulumi/tap/esc

Verify installation ESC version

➜ esc version
v0.8.0

Configure Pulumi to access your AWS account

만일, 이미 AWS CLI를 설정해 놓은 경우 Pulumi에서 이 정보를 읽어올 수 있습니다.

export AWS_ACCESS_KEY_ID="<YOUR_ACCESS_KEY_ID>"
export AWS_SECRET_ACCESS_KEY="<YOUR_SECRET_ACCESS_KEY>"
export AWS_PROFILE="<YOUR_PROFILE_NAME>"

기본 사용법

이어지는 내용에서는 Pulumi를 사용하여 클라우드 리소스(AWS) 프로젝트 생성부터 AWS S3 버킷을 배포하고, 웹사이트 호스팅 설정까지의 전체 프로세스를 다룹니다.

Create new project

💡 pulumi를 처음 사용한다면 로그인 토큰을 입력하거나, 브라우저에서 pulumi 계정으로 로그인이 필요합니다.

Project, Stack, Region 설정

# create project dir
➜ mkdir quickstart && cd quickstart

# create pulumi project
➜ pulumi new aws-python
This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.

project name (quickstart):  
project description (A minimal AWS Python Pulumi program):  
Created project 'quickstart'

Please enter your desired stack name.
To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
stack name (dev):  
Created stack 'dev'

aws:region: The AWS region to deploy into (us-east-1): ap-northeast-2 
Saved config

Installing dependencies...

Creating virtual environment...

## 중략

Finished installing dependencies

Your new project is ready to go! ✨

To perform an initial deployment, run `pulumi up`

명령이 완료되면 프로젝트와 스택이 준비됩니다.

Pulumi 프로젝트의 구성

Pulumi는 폴더 단위의 프로젝트로 구성되어 있습니다. aws-python 템플릿의 경우, 기본적인 폴더의 구조는 다음과 같습니다.

Pulumi tree

➜ tree -L 2
.
├── Pulumi.dev.yaml
├── Pulumi.yaml
├── __main__.py
├── requirements.txt
└── venv
    ├── bin
    ├── include
    ├── lib
    └── pyvenv.cfg
  • Pulumi.yaml: 프로젝트를 정의합니다.
  • Pulumi.dev.yaml: 초기화된 스택의 구성 값을 포함합니다.
  • __main__.py: 스택 리소스를 정의하는 Pulumi 프로그램입니다.
  • requirements.txt: 프로젝트 의존성 목록입니다.
  • venv: 파이썬 가상 환경 디렉토리입니다.

기본 제공되는 __main__.py 파일은 S3 버킷을 생성하고, 버킷 이름을 출력하는 예제 코드를 포함합니다.

"""An AWS Python Pulumi program"""

import pulumi
from pulumi_aws import s3

# Create an AWS resource (S3 Bucket)
bucket = s3.Bucket('pulumi-jeff')

# Export the name of the bucket
pulumi.export('bucket_name', bucket.id)

Project VS Stack

Pulumi 프로젝트와 스택은 Pulumi 코드를 조직화하는 데 도움을 줍니다.

Pulumi의 프로젝트는 GitHub 저장소와 유사하게 생각할 수 있습니다. 즉, 코드를 위한 단일한 장소입니다.

반면에 스택은 그 코드의 인스턴스로, 별도의 구성을 가집니다.

예를 들어, foo라는 프로젝트는 다른 배포 환경(dev, test, 또는 production)을 위한 여러 스택을 가질 수 있으며, 또는 다른 클라우드 구성을 위한 스택을 가질 수도 있습니다.

Deploy stack

➜ pulumi up            
Previewing update (dev)

View in Browser (Ctrl+O): <https://app.pulumi.com/dewble/quickstart/dev/previews/13c3c203-59a3-47c2-9a97-e128e3678b89>

Downloading plugin: 220.71 MiB / 220.71 MiB  100.00% 10s

[resource plugin aws-6.28.2] installing
     Type                 Name            Plan       
 +   pulumi:pulumi:Stack  quickstart-dev  create     
 +   └─ aws:s3:Bucket     my-bucket       create     

Outputs:
    bucket_name: output

Resources:
    + 2 to create

Do you want to perform this update?  [Use arrows to move, type to filter]
> yes
  no
  details

You can check results from View in Browser URL

You can access your outputs from the CLI by running the pulumi stack output [property-name] command.

➜ pulumi stack output bucket_name

my-bucket-dbbd2bc

Modify program - Docs

Create index.html

echo '<html>
    <body>
        <h1>Hello, Pulumi!</h1>
    </body>
</html>' > index.html

edit __main__py

# Create an S3 Bucket object
bucketObject = s3.BucketObject(
    'index.html',
    bucket=bucket.id,
    source=pulumi.FileAsset('./index.html')
)

Deploy changes

➜ pulumi up    
Previewing update (dev)

View in Browser (Ctrl+O): <https://app.pulumi.com/dewble/quickstart/dev/previews/622517cc-5d68-4fd9-a64e-86c7ddf6180e>

     Type                    Name            Plan     
     pulumi:pulumi:Stack     quickstart-dev           
 +   └─ aws:s3:BucketObject  index.html      create   

Resources:
    + 1 to create
    2 unchanged

Do you want to perform this update? yes
Updating (dev)

View in Browser (Ctrl+O): <https://app.pulumi.com/dewble/quickstart/dev/updates/2>

     Type                    Name            Status   
     pulumi:pulumi:Stack     quickstart-dev           
 +   └─ aws:s3:BucketObject  index.html      created (

Outputs:
    bucket_name: "my-bucket-dbbd2bc"

Resources:
    + 1 created
    2 unchanged

Duration: 13s

pulumi up 이 명령은 수정된 프로그램을 프리뷰하고, index.html 파일을 버킷에 업로드합니다.

➜ aws s3 ls $(pulumi stack output bucket_name)
2024-03-30 21:47:31         70 index.html

Update the program

이번 섹션에서는 AWS S3 버킷을 웹사이트로 호스팅 하는 Pulumi 프로그램을 업데이트하는 방법을 소개합니다. 웹사이트를 호스팅 하기 위해 S3 버킷을 설정하고, 공개 액세스를 허용하는 설정을 추가하는 과정을 다룹니다.

"""An AWS Python Pulumi program"""

import pulumi
from pulumi_aws import s3

# Create an AWS resource (S3 Bucket)
bucket = s3.Bucket("my-bucket",
    website=s3.BucketWebsiteArgs(
        index_document="index.html",
    ),
)

버킷 자체에 대해서는 두 가지 새로운 리소스가 필요합니다:

  1. 파일 소유권 설정을 정의하는 BucketOwnershipControls 리소스
  2. 버킷을 공개적으로 접근 가능하게 하는 BucketPublicAccessBlock 리소스

BucketObject에 대해서는 public-read 액세스 제어(ACL) 설정이 필요합니다. 이 설정은 페이지를 익명으로 접근 가능하게 하며, text/html 콘텐츠 타입은 AWS에게 파일을 웹 페이지로 제공하도록 지시합니다.

ownership_controls = s3.BucketOwnershipControls(
    'ownership-controls',
    bucket=bucket.id,
    rule=s3.BucketOwnershipControlsRuleArgs(
        object_ownership='ObjectWriter',
    ),
)

public_access_block = s3.BucketPublicAccessBlock(
    'public-access-block', bucket=bucket.id, block_public_acls=False
)

bucket_object = s3.BucketObject(
    'index.html',
    bucket=bucket.id,
    source=pulumi.FileAsset('index.html'),
    content_type='text/html',
    acl='public-read',
    opts=pulumi.ResourceOptions(depends_on=[public_access_block, ownership_controls]),
)

버킷의 엔드포인트 URL을 내보내어 쉽게 브라우징 할 수 있도록 합니다:

pulumi.export('bucket_endpoint', pulumi.Output.concat('http://', bucket.website_endpoint))

최종코드

최종적으로 업데이트된 코드는 S3 버킷을 웹사이트로 호스팅 하도록 구성하고, 공개 액세스를 허용합니다. 버킷 이름과 엔드포인트 URL이 출력됩니다.

"""An AWS Python Pulumi program"""

import pulumi
from pulumi_aws import s3

# Create an AWS resource (S3 Bucket)
bucket = s3.Bucket("my-bucket",
    website=s3.BucketWebsiteArgs(
        index_document="index.html",
    ),
)

ownership_controls = s3.BucketOwnershipControls(
    'ownership-controls',
    bucket=bucket.id,
    rule=s3.BucketOwnershipControlsRuleArgs(
        object_ownership='ObjectWriter',
    ),
)

public_access_block = s3.BucketPublicAccessBlock(
    'public-access-block', bucket=bucket.id, block_public_acls=False
)

bucket_object = s3.BucketObject(
    'index.html',
    bucket=bucket.id,
    source=pulumi.FileAsset('index.html'),
    content_type='text/html',
    acl='public-read',
    opts=pulumi.ResourceOptions(depends_on=[public_access_block, ownership_controls]),
)

# Export the name of the bucket
pulumi.export('bucket_name', bucket.id)
pulumi.export('bucket_endpoint', pulumi.Output.concat('http://', bucket.website_endpoint))

Deploy the website

➜ pulumi up                                   
Previewing update (dev)

View in Browser (Ctrl+O): <https://app.pulumi.com/dewble/quickstart/dev/previews/2a274de9-aee4-4d6f-87af-2c69fbfbb1ee>

     Type                               Name          
     pulumi:pulumi:Stack                quickstart-dev
 ~   ├─ aws:s3:Bucket                   my-bucket     
 +   ├─ aws:s3:BucketOwnershipControls  ownership-cont
 +   ├─ aws:s3:BucketPublicAccessBlock  public-access-
 ~   └─ aws:s3:BucketObject             index.html    

Outputs:
  + bucket_endpoint: output

Resources:
    + 2 to create
    ~ 2 to update
    4 changes. 1 unchanged

Do you want to perform this update? yes
Updating (dev)

View in Browser (Ctrl+O): <https://app.pulumi.com/dewble/quickstart/dev/updates/3>

     Type                               Name          
     pulumi:pulumi:Stack                quickstart-dev
 ~   ├─ aws:s3:Bucket                   my-bucket     
 +   ├─ aws:s3:BucketOwnershipControls  ownership-cont
 +   ├─ aws:s3:BucketPublicAccessBlock  public-access-
 ~   └─ aws:s3:BucketObject             index.html    

Outputs:
  + bucket_endpoint: "<http://my-bucket-dbbd2bc.s3-website.ap-northeast-2.amazonaws.com>"
    bucket_name    : "my-bucket-dbbd2bc"

Resources:
    + 2 created
    ~ 2 updated
    4 changes. 1 unchanged

Duration: 17s

웹사이트를 배포하기 위해 pulumi up 명령을 실행합니다. 이 과정에서 버킷, 버킷 객체, 소유권 및 공개 액세스 설정이 생성 또는 업데이트됩니다. 배포가 완료되면, 출력 섹션에서 버킷 엔드포인트 URL을 확인할 수 있습니다.

➜ curl $(pulumi stack output bucket_endpoint)
<html>
    <body>
        <h1>Hello, Pulumi!</h1>
    </body>
</html>

Destroy Stack - Docs

To destroy resources, run the following:

➜ pulumi destroy

Previewing destroy (dev)

View in Browser (Ctrl+O): <https://app.pulumi.com/dewble/quickstart/dev/previews/a63be726-0d5d-4e1d-ae4e-51a2539b9a6f>

     Type                               Name          
 -   pulumi:pulumi:Stack                quickstart-dev
 -   ├─ aws:s3:BucketObject             index.html    
 -   ├─ aws:s3:BucketPublicAccessBlock  public-access-
 -   ├─ aws:s3:BucketOwnershipControls  ownership-cont
 -   └─ aws:s3:Bucket                   my-bucket     

Outputs:
  - bucket_endpoint: "<http://my-bucket-dbbd2bc.s3-website.ap-northeast-2.amazonaws.com>"
  - bucket_name    : "my-bucket-dbbd2bc"

Resources:
    - 5 to delete

Do you want to perform this destroy? yes
Destroying (dev)

View in Browser (Ctrl+O): <https://app.pulumi.com/dewble/quickstart/dev/updates/4>

     Type                               Name                 Status              
 -   pulumi:pulumi:Stack                quickstart-dev       deleted (0.61s)     
 -   ├─ aws:s3:BucketObject             index.html           deleted (1s)        
 -   ├─ aws:s3:BucketOwnershipControls  ownership-controls   deleted (1s)        
 -   ├─ aws:s3:BucketPublicAccessBlock  public-access-block  deleted (2s)        
 -   └─ aws:s3:Bucket                   my-bucket            deleted (1s)        

Outputs:
  - bucket_endpoint: "<http://my-bucket-dbbd2bc.s3-website.ap-northeast-2.amazonaws.com>"
  - bucket_name    : "my-bucket-dbbd2bc"

Resources:
    - 5 deleted

Duration: 16s

The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained. 
If you want to remove the stack completely, run `pulumi stack rm dev`.

프로젝트와 관련된 모든 리소스를 제거하려면 pulumi destroy 명령을 실행합니다. 이 명령은 버킷, 버킷 객체, 소유권 및 공개 액세스 설정을 포함한 모든 리소스를 삭제합니다. 리소스 삭제 후, 스택을 완전히 제거하고자 한다면 pulumi stack rm dev 명령을 사용하여 스택을 삭제할 수 있습니다.

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.