Overview
오늘은 pulumi에 대해서 공부해보려고 한다.
Pulumi란?
pulumi는 프로그래밍 언어를 사용하여 인프라 코드를 작성한다.
IDE를 사용하여 인프라를 정의하는 문장을 자동 완성도 할 수 있다. 그리고, 단위 테스트를 통해 코드를 테스트하고 CI/CD 파이프라인을 사용하여 코드를 전달하며 클라우드에 대한 검증 및 배포를 수행한다.
SDK는 다양한 언어를 제공한다. 예를 들어 C# .NET
앱을 작업하는 팀은 C# .NET
에서도 클라우드 인프라를 구현하는 데 관심이 있을 수 있다. 아니면 JS
에 React
기반 앱을 작업하는 팀과 클라우드 인프라에도 JS
를 사용하려는 Node.js
생태계도 있다.
Terraform vs Pulumi
Pulumi와 Terraform은 모두 IaC(Infrastructure as Code) 도구이다.
pulumi는 Devops Engineer가 없는 스타트업에서 개발자가 인프라를 IaC 도구로 구축하기에 쉽고 흥미로울 수 있다.
다만, Terraform은 HashiCorp Configuration Language 구성되어 있고 사람이 읽을 수 있고 다른 프로그래밍 언어에 익숙하지 않은 경우에 배우기 쉽다.
Pulumi와 Terraform은 선언적(declarative)이다 . Pulumi를 사용하면 명령형 언어로 코드를 작성하면 해당 엔진이 이를 실행을 위해 선언적 그래프로 변환한다. 이를 통해 Pulumi 프로그램을 실행할 때마다 결과와 효과가 항상 동일하다는 멱등성(idempotent)을 보장한다. 이는 Terraform과 유사하지만 코드를 작성하는 방식은 다르다.
Pulumi 설치 및 실습
설치 및 실습에 대해 설명하기전에 실습환경은 window wsl2(ubuntu 20.04)를 사용하여 실습한다.
그리고 Cloud 환경(GCP)을 사용할 것이다. SDK는 Python을 사용한다.
https://github.com/somaz94/pulumi-study
Python 확인
ubuntu WSL에는 기본적으로 python이 설치되어 있다. 그러나, python2와 3가 둘다 설치되어 있기 때문에 셋팅을 해줘야 한다.
# ubuntu WSL 사용
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.5 LTS
Release: 20.04
Codename: focal
# python version 확인
python3
Python 3.8.10 (default, Mar 13 2023, 10:26:41)
python2
Python 2.7.18 (default, Jun 1 2023, 14:30:11)
# python version 셋팅
pyenv global 3.8.10 2.7.18
pyenv: version `3.8.10' not installed
pyenv install 3.8.10
Downloading Python-3.8.10.tar.xz...
-> https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tar.xz
Installing Python-3.8.10...
patching file Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst
patching file configure
patching file configure.ac
Installed Python-3.8.10 to /home/somaz/.pyenv/versions/3.8.10
pyenv global 3.8.10 2.7.18
pip3 --version
pip 21.1.1 from /home/somaz/.pyenv/versions/3.8.10/lib/python3.8/site-packages/pip (python 3.8)
pip2 --version
pip 19.2.3 from /home/somaz/.pyenv/versions/2.7.18/lib/python2.7/site-packages/pip (python 2.7)
Pulumi 설치 및 CLI
## Install ##
# Linux
curl -fsSL https://get.pulumi.com | sh
# macOS
brew install pulumi/tap/pulumi
----------------------------------------
## CLI ##
# Create a new project
pulumi new
# Manage and view state
pulumi stack
# configure variables such as keys, regions, and so on
pulumi config
# preview and deploy changes to your program and/or infrastructure
pulumi up
# preview your changes explicitly before deploying
pulumi preview
# destroy your program and its infrastructure when you’re done
pulumi destroy
# Set the default destination org for all stack operations
pulumi org set-default NAME
View backend, current stack, pending operations, and versions
pulumi about
Pulumi 프로젝트 생성
처음으로 'pulumi new' 를 하거나 다른 명령을 실행하는 경우 Pulumi Cloud에 로그인하라는 메시지가 나타난다.
개인용으로 무료이며 팀에서 사용할 수 있는 기능이 있으며 자체 관리 옵션 도 사용할 수 있다.
프롬프트에서 Enter를 누르면 로그인하거나 가입할 수 있는 브라우저가 열린다.
Project : quickstart
Stack : dev
GCP Project : Somaz
mkdir quickstart && cd quickstart && pulumi new gcp-python
-bash: pulumi: command not found
...
# Shell Restart
exec bash
# Confirm PATH
echo $PATH
# Reinstall Pulumi
pulumi new gcp-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 Google Cloud 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'
gcp:project: The Google Cloud project to deploy into: somaz
프로젝트를 생성하면 기본적으로 아래와 같은 파일들이 생성된다.
ls
Pulumi.dev.yaml Pulumi.yaml __main__.py requirements.txt venv
cat Pulumi.dev.yaml
config:
gcp:project: somaz
cat Pulumi.yaml
name: quickstart
runtime:
name: python
options:
virtualenv: venv
description: A minimal Google Cloud Python Pulumi program
cat __main__.py
"""A Google Cloud Python Pulumi program"""
import pulumi
from pulumi_gcp import storage
# Create a GCP resource (Storage Bucket)
bucket = storage.Bucket('my-bucket', location="US")
# Export the DNS name of the bucket
pulumi.export('bucket_name', bucket.url)
cat requirements.txt
pulumi>=3.0.0,<4.0.0
pulumi-gcp>=6.0.0,<7.0.0
Pulumi 실습
간단하게 GCS Bucket을 먼저 생성해본다.
코드를 수정해준다.
cat __main__.py
"""A Google Cloud Python Pulumi program"""
import pulumi
from pulumi_gcp import storage
# Create a GCP resource (Storage Bucket)
bucket = storage.Bucket('somaz-test', location="asia-northeast3")
# Export the DNS name of the bucket
pulumi.export('bucket_name', bucket.url)
코드를 실행해준다.
pulumi up
Previewing update (dev)
View in Browser (Ctrl+O): https://app.pulumi.com/somaz94/quickstart/dev/previews/929650e1-83c3-45b5-b4c3-16d676c527aa
Type Name Plan
+ pulumi:pulumi:Stack quickstart-dev create
+ └─ gcp:storage:Bucket somaz-test create
Outputs:
bucket_name: output<string>
Resources:
+ 2 to create
Do you want to perform this update? yes
Updating (dev)
View in Browser (Ctrl+O): https://app.pulumi.com/somaz94/quickstart/dev/updates/1
Type Name Status
+ pulumi:pulumi:Stack quickstart-dev created (4s)
+ └─ gcp:storage:Bucket somaz-test created (2s)
Outputs:
bucket_name: "gs://somaz-test-da574fe"
Resources:
+ 2 created
Duration: 6s
실행을 하면 위와같이 Pulumi Cloud에 배포된 내용이 보이고, GCS bucket에서도 잘 배포된 것을 확인할 수 있다.
gsutil ls $(pulumi stack output bucket_name)
gs://somaz-test-da574fe
그렇다면 이번에는 다른 설정들을 좀 더 추가하여 GCS bucket을 생성해본다.
- UBLA 설정
- random-suffix 삭제
- index.html 추가 후 공개 액세스 허용
- 버킷에 존재하는 파일을 정적 웹 사이트로 제공
__main__.py
"""A Google Cloud Python Pulumi program"""
import pulumi
from pulumi_gcp import storage
# Create a GCP resource (Storage Bucket) with uniform access control and explicit name
bucket = storage.Bucket('somaz-test-resource',
name="somaz-test", # This sets the exact name of the bucket
location="asia-northeast3",
website=storage.BucketWebsiteArgs(main_page_suffix="index.html"),
uniform_bucket_level_access=True) # Enable uniform bucket-level access
# In __main__.py, create a new bucket object by adding the following right after creating the bucket itself
bucket_object = storage.BucketObject(
"index.html", bucket=bucket.name, source=pulumi.FileAsset("index.html")
)
# Below the BucketObject, add an IAM binding allowing the contents of the bucket to be viewed anonymously over the Internet
bucket_iam_binding = storage.BucketIAMBinding(
"somaz-test-binding",
bucket=bucket.name,
role="roles/storage.objectViewer",
members=["allUsers"],
)
# Export the DNS name of the bucket
pulumi.export('bucket_name', bucket.url)
pulumi.export(
"bucket_endpoint",
pulumi.Output.concat(
"http://storage.googleapis.com/", bucket.id, "/", bucket_object.name
),
)
index.html
<html>
<body>
<h1>Hello, Pulumi!</h1>
</body>
</html>
코드를 실행해준다.
pulumi up
Previewing update (dev)
View in Browser (Ctrl+O): https://app.pulumi.com/somaz94/quickstart/dev/previews/22d8de56-5764-4759-97a5-3c9f80957f52
Type Name Plan
pulumi:pulumi:Stack quickstart-dev
Outputs:
+ bucket_name : "gs://somaz-test"
Resources:
4 unchanged
Do you want to perform this update? yes
Updating (dev)
View in Browser (Ctrl+O): https://app.pulumi.com/somaz94/quickstart/dev/updates/7
Type Name Status
pulumi:pulumi:Stack quickstart-dev
Outputs:
bucket_endpoint: "http://storage.googleapis.com/somaz-test/index.html-b80376b"
+ bucket_name : "gs://somaz-test"
Resources:
4 unchanged
Duration: 3s
아래와 같이 잘 확인이 가능하다.
마지막으로 리소스를 삭제해준다.
# Destroy stack
pulumi destroy
pulumi stack rm dev
This will permanently remove the 'dev' stack!
Please confirm that this is what you'd like to do by typing `dev`: dev
Stack 'dev' has been removed!
다음시간에는 아래의 내용들을 공부해본다.
- Pulumi state 관리
- Pulumi resource file을 잃어버렸을때 state 삭제 방법
- Github에서 Pulumi 소스 코드를 가져와 사용하는 방법
- Pulumi VPC , GCE 배포해보기
Reference
https://github.com/somaz94/pulumi-study
https://www.pulumi.com/
https://spacelift.io/blog/what-is-pulumi
https://www.pulumi.com/docs/clouds/gcp/get-started/
'IaC > Infrastructure Provisioning' 카테고리의 다른 글
2. Pulumi 활용 (2) | 2023.10.04 |
---|---|
Terraformer란? (0) | 2023.05.04 |
5. Terraform의 다양한 Expression (0) | 2023.04.13 |
4. Terraform의 다양한 Function(함수) (0) | 2023.04.11 |
3. Terraform 다양한 변수(variable, local, data...output, input) - AWS (0) | 2023.04.09 |