์๋ ํ์ธ์ ๊ตฌ๋ ์๋, IT ์ฌํ์๋ฅผ ์ํ ์์์ง์ ๋๋ค.
์ฐ๋ฆฌ๊ฐ ์ง๋ ๊ธ์์ IaC๊ฐ ํ์ํ ์ด์ ์ Pulumi์ ๋์ ๋ฐฉ์๊น์ง ์ดํด๋ดค๋๋ฐ์.
์ด๋ฒ ๊ธ์์๋ Pulumi๋ฅผ ํ์ฉํด์ AWS SQS๋ฅผ ๋ฐฐํฌํ๋ ๊ณผ์ ์ ํตํด Pulumi์ ํต์ฌ ์ํฌํ๋ก์ฐ๋ฅผ ์ ๋ฆฌํด๋ดค์ต๋๋ค.
์ ๊ฐ ์ง์ ํ ์คํธํ๋ฉด์ ์์ฑํ ๊ฐ์ด๋์ด๋, IaC์ Pulumi์ ๊ด์ฌ ์์ผ์๋ค๋ฉด ๊ผญ ํ์ธํด์ฃผ์ธ์!
* ํ์ฌ ๋ณธ ํ๋ซํผ์ ์ค์ต ๊ฐ์ด๋์ ํ์ํ ๋งํฌ๋ค์ด ๋ฌธ๋ฒ์ด ๋ชจ๋ ์ง์ํ์ง ์๋ ๊ด๊ณ๋ก, ๋ณด๋ค ๋์ ์ค์ต ๊ฒฝํ์ ์ํด ์๋ ํ์ด์ง์์ ๊ฐ์ด๋๋ฅผ ํ์ธํ์๋ ๊ฑธ ์ถ์ฒ๋๋ ค์!
(๊ฐ์ด๋ ๋ด์ฉ์ ๋ชจ๋ ๋์ผํฉ๋๋ค.)
๐https://aidenslab-newsletter.beehiiv.com/p/pulumi-python-aws-pulumi-cd04fed1b6a229e8
1๏ธโฃPulumi ์ค์น ๋ฐ AWS ๊ณ์ ์ค์
Pulumi๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋จผ์ ์ฌ์ฉ ์ค์ธ PC์ Pulumi CLI๋ฅผ ์ค์นํ๊ณ , AWS ๊ณ์ ์ค์ ์ ๋ง์ณ์ผ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ Python ํจํค์ง ๊ด๋ฆฌ์ pip์ ๊ฐ์ ํ๊ฒฝ venv๊ฐ ๋ฏธ๋ฆฌ ์ค์น๋์ด ์์ด์ผ ํฉ๋๋ค.
์ ๋ WSL ํ๊ฒฝ์ด๊ธฐ ๋๋ฌธ์ ์๋ ๋ช ๋ น์ด๋ฅผ ํฐ๋ฏธ๋์์ ์คํํด Pulumi๋ฅผ ์ค์นํ์ต๋๋ค.
curl -fsSL https://get.pulumi.com | sh
์๋์ผ๋ก Pulumi ์ค์น ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋์ด์ ์ค์น๊ฐ ์๋ฃ๋๋ฉด ์๋์ ๊ฐ์ด Pulumi ๋ฒ์ ์ ์กฐํํ ์ ์๊ฒ ๋ฉ๋๋ค.
Pulumi๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด Pulumi ํด๋ผ์ฐ๋์ ๋ก๊ทธ์ธ์ ํ๊ฑฐ๋ ๋ก์ปฌ ๋ก๊ทธ์ธ์ ํด์ผ ํฉ๋๋ค. ์ง๊ธ์ ๋น ๋ฅธ ์ค์ต์ ์ํด ์๋ ๋ช ๋ น์ด๋ก ๋ก์ปฌ ๋ก๊ทธ์ธ์ ํ๊ฒ ์ต๋๋ค.
pulumi login --local
๊ทธ๋ผ ์๋์ ๊ฐ์ด ํ์ฌ ์ฌ์ฉ์ ์ด๋ฆ์ผ๋ก ๋ก๊ทธ์ธ๋์๋ค๊ณ ํ์๋ฉ๋๋ค.
๋ค์์ ํด๋ผ์ฐ๋ ๊ณ์ ์ค์ ์ธ๋ฐ์. Pulumi CLI๊ฐ AWS ๋ฆฌ์์ค๋ฅผ ์์ฑํ๊ฑฐ๋ ๊ด๋ฆฌํ๋ ค๋ฉด ์ฌ์ฉ ์ค์ธ AWS ๊ณ์ ์ ๋ณด๋ฅผ ์์์ผ ํฉ๋๋ค.
๋ง์ฝ ๋ก์ปฌ์ ์ด๋ฏธ AWS CLI๊ฐ ์ค์น๋์ด ์๋ค๋ฉด ๋ณ๋์ ๊ณ์ ์ค์ ์ ํ์ ์์ง๋ง, AWS CLI๋ฅผ ์ค์นํ์ง ์์๊ฑฐ๋ CI/CD์์ Pulumi๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ ์๋์ฒ๋ผ AWS Access Key ID์ AWS Secret Access Key๊ฐ ๋ก์ปฌ ํ๊ฒฝ๋ณ์์ ์ ์ฅ๋์ด ์์ด์ผ ํฉ๋๋ค.
export AWS_ACCESS_KEY_ID="<AWS ๊ณ์ ์ ACCESS KEY ID>"
export AWS_SECRET_ACCESS_KEY="<AWS ๊ณ์ ์ SECRET ACCESS KEY>"
2๏ธโฃ์๋ก์ด Pulumi ํ๋ก์ ํธ ์์ฑ
์ด์ Pulumi๋ฅผ ์์ํ ์ค๋น๊ฐ ๋๋ฌ์ต๋๋ค. ์ํ๋ ํด๋๋ก ์ด๋ํ ๋ค์ ์๋ก์ด Pulumi ํ๋ก์ ํธ๋ฅผ ์์ฑํด๋ณด์ฃ . ๋ณธ ๊ฐ์ด๋๋ AWS ์ธํ๋ผ ๊ด๋ฆฌ๋ฅผ Python์ผ๋ก ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ aws-python์ด๋ ํ ํ๋ฆฟ ์ด๋ฆ์ ๋ถ์ธ ์๋ ๋ช ๋ น์ด๋ฅผ ์คํํฉ๋๋ค.
pulumi new aws-python
๊ทธ๋ฌ๋ฉด ์๋ ์ด๋ฏธ์ง์ ๊ฐ์ด ํฐ๋ฏธ๋ ์์์ ํ๋ก์ ํธ ์ด๋ฆ๊ณผ ์ค๋ช , ์คํ ์ด๋ฆ, ๋น๋ฐ๋ฒํธ, ํจํค์ง ๊ด๋ฆฌ์, AWS ๋ฆฌ์ ์ ์ค์ ํ๊ฒ ๋ฉ๋๋ค.
์ด ๊ณผ์ ๊น์ง ๋ฌด์ฌํ ๋ง์น๋ฉด Pulumi ํ๋ก์ ํธ ์์ฑ์ ์ฑ๊ณต์ ๋๋ค!๐
ํด๋น ๊ฒฝ๋ก์ ์๋์ ๊ฐ์ด ๊ธฐ๋ณธ์ ์ธ ํ๋ก์ ํธ ๊ตฌ์กฐ์ ์์ ์ฝ๋๊ฐ ์์ฑ๋ ๊ฒ์ ํ์ธํ ์ ์๋๋ฐ์.
Pulumi ๋์์ ํ์ํ ํต์ฌ ํ์ผ์ ์๋์ ๊ฐ์ต๋๋ค.
- Pulumi.yaml: ํ๋ก์ ํธ์ ๋ฉํ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ ํ์ผ
- Pulumi.<์คํ๋ช >.yaml: ํน์ ์คํ(์: dev, prod)์ ๊ตฌ์ฑ ๊ฐ์ ์ ์ฅ๋ ํ์ผ
- __main__.py: ์ค์ ์ธํ๋ผ ์ฝ๋๋ฅผ ์์ฑํ ํ์ผ
- requirements.txt: ์์กด์ฑ ๊ด๋ฆฌ ํ์ผ
"๊ทธ๋ ๊ตฐ์... ๊ทผ๋ฐ ์คํ์ด ๋ญ์์?"
์๊น๋ถํฐ ์คํ์ด๋ ์ฉ์ด๊ฐ ๊ณ์ ๋์์ ๊ถ๊ธํ์ค ์ ์๋๋ฐ์.
Pulumi๋ ๋์ผํ ์ธํ๋ผ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋, ์๋ก ๊ฒฉ๋ฆฌ๋ ์ธ์คํด์ค๋ฅผ ๊ตฌ์ฑํ ์ ์๋๋ก ํ์ต๋๋ค. ๊ทธ๊ฑธ Pulumi์์ ์คํ์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
์๋ฅผ ๋ค์ด, dev, staging, production๊ณผ ๊ฐ์ด ๊ฐ๊ธฐ ๋ค๋ฅธ ๋ชฉ์ ์ ํ๊ฒฝ์ ๋์ผํ ์ฝ๋๋ก ๊ด๋ฆฌํ ์ ์๋ ๊ฒ์ด์ฃ .
๊ฐ ์คํ์ ์์ ๋ง์ ๊ตฌ์ฑ ์ค์ ๊ณผ ์ํ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ํ๋์ ์คํ์ด ๋ณ๊ฒฝ๋์๋ค๊ณ ํด์ ๋ค๋ฅธ ์คํ์ ์ํฅ์ ์ฃผ์ง ์์ต๋๋ค.
3๏ธโฃPulumi ์ธํ๋ผ ๊ด๋ฆฌ ์ฝ๋ ์์ฑ
๋ค์ Pulumi ํ๋ก์ ํธ๋ก ๋์์ค๊ฒ ์ต๋๋ค. ํ๋ก์ ํธ๋ฅผ ์๋ก ์์ฑํ ๋ ๋ง๋ค์ด์ง ์ค์ ์ธํ๋ผ ์ฝ๋(__main__.py)์๋ AWS S3 ๋ฒํท์ ์์ฑํ๋ ์์ ์ฝ๋๊ฐ ๋ค์ด์์ ํ ๋ฐ์.
S3 ๋ฒํท์ ์์ฑํ๋ ์์ ์ฝ๋๋ ์ข์ง๋ง, ๋ณธ ๊ฐ์ด๋์์๋ ์ ํ๋ฆฌ์ผ์ด์ ํ์ฅ์ฑ๊ณผ ์์ ์ฑ์ ๋์ผ ๋ ์์ฃผ ์ฌ์ฉ๋๋ AWS SQS ๋ฆฌ์์ค ์์ฑ ์์ ๋ฅผ ์ค๋นํ์ต๋๋ค.
AWS SQS๊ฐ ๋ฌด์์ธ์ง ๊ถ๊ธํ์ ๋ถ๋ ๊ณ์ค ํ ๋ฐ์.
SQS๋ ์์ ๊ด๋ฆฌํ ๋ฉ์์ง ๋๊ธฐ์ด ์๋น์ค๋ก, ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ฑ ์์ ๊ฐ์ ์ด๋ค ๋ฉ์์ง๋ ์์ ์ ์ผ๋ก ์ ์ก, ์ ์ฅ, ์์ ํ ์ ์๋๋ก ๋์์ค๋๋ค.
์ข ๋ ์์ธํ ์ค๋ช ์ด ๊ถ๊ธํ์๋ค๋ฉด ์ ๊ฐ ์ง๋๋ฒ์ AWS SQS์ SNS๋ฅผ ๋น๊ตํ ๊ธ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
๊ทธ๋ผ, ์ด์ ์ธํ๋ผ ์ฝ๋ ํ์ผ(__main__.py)์ ์๋ AWS SQS ์์ฑ ์์ ์ฝ๋๋ฅผ ๋ฃ์ด์ค๋๋ค.
import pulumi
import pulumi_aws as aws
# SQS ์์ฑ
# mySimpleQueue๋ Pulumi ํ๋ก๊ทธ๋จ ๋ด์์ ์ด ๋ฆฌ์์ค๋ฅผ ์๋ณํ๋ ๋ ผ๋ฆฌ์ ์ด๋ฆ
my_queue = aws.sqs.Queue("mySimpleQueue",
name="my-app-queue", # ์ค์ ์์ฑ๋ ํ ์ด๋ฆ (์ ํ ์ฌํญ, ์ง์ ์ํ๋ฉด Pulumi๊ฐ ์๋ ์์ฑ)
tags={
"Environment": "dev",
"Project": "MyNewsletterApp",
})
# ์์ฑ๋ SQS Queue์ ์ ๋ณด ์ถ๋ ฅ
# pulumi.export()๋ฅผ ์ฌ์ฉํ๋ฉด `pulumi up` ์คํ ํ ํฐ๋ฏธ๋์ ํด๋น ๊ฐ ์ถ๋ ฅ
pulumi.export("queue_url", my_queue.id) # ์์ฑ๋ SQS์ URL ๋ฐํ
pulumi.export("queue_arn", my_queue.arn) # ์์ฑ๋ SQS์ Amazon Resource Name (ARN) ๋ฐํ
4๏ธโฃPulumi๋ก ์ธํ๋ผ ๋ฆฌ์์ค ๋ฐฐํฌ
์ธํ๋ผ ๊ด๋ฆฌ ์ฝ๋ ์์ฑ์ ์๋ฃํ๋ค๋ฉด ์ด์ Pulumi๋ก ์ค์ ์ธํ๋ผ ๋ฆฌ์์ค๋ฅผ ๋ฐฐํฌํด์ผ๊ฒ ์ฃ ?
๋ฌผ๋ก ๋ฐ๋ก ๋ฐฐํฌํ ์๋ ์์ง๋ง, ์ธํ๋ผ๋ฅผ ์์ ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด ์๋ ์ํฌํ๋ก์ฐ๋ฅผ ๋ฐ๋ฅผ ๊ฒ์ ๊ถ์ฅ๋๋ฆฝ๋๋ค.
1. pulumi preview ๋ช ๋ น์ด๋ฅผ ์คํํ์ฌ ์ค์ ์ธํ๋ผ ๋ณ๊ฒฝ ์์ด ์์ ๋ ์์ ์ ๋ฏธ๋ฆฌ ํ์ธ
2. pulumi up ๋ช ๋ น์ด๋ฅผ ์คํํ์ฌ ์ค์ ์ธํ๋ผ๋ฅผ ์์ฑ ๋ฐ ์ ๋ฐ์ดํธ
pulumi preview ๋ช ๋ น์ด๋ฅผ ๋จผ์ ์คํํ๋ฉด ์๋์ ๊ฐ์ด ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ผ๋ ์๋ด ํ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
์๊น ์ธํ๋ผ ๊ด๋ฆฌ ์ฝ๋์์ ์์ฑํ๋ ค๊ณ ํ๋ SQS๊ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์๋ ์ ํ์๋๊ณ ์๋ค์.
๊ทธ๋ผ pulumi up ๋ช ๋ น์ด๋ก ์ค์ AWS SQS๋ฅผ ๋ฐฐํฌํด๋ณด๊ฒ ์ต๋๋ค!
๋ช ๋ น์ด๋ฅผ ์คํํ๋ฉด ์๊น pulumi preview ๋ช ๋ น์ด๋ฅผ ์คํํ ๋์ฒ๋ผ ๋จผ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ผ๋ ์๋ด ํ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
๊ทธ ๋ค์ ์ ๋ฐ์ดํธ๋ฅผ ์งํํ๊ฒ ๋๋ ์ง๋ฌธ์ yes๋ฅผ ์ ํํ๋ฉด, ์๋์ฒ๋ผ ์ค์ ์ธํ๋ผ ๋ฆฌ์์ค๊ฐ ์์ฑ๋ ๋ค์ SQS URL๊ณผ ARN์ด ํ์๋ฉ๋๋ค.
์๋๋ pulumi up ๋ช ๋ น์ด ์คํ ์ AWS ์ฝ์์ SQS ํ์ด์ง์ ๋๋ค. ๋ณด์ด๋ ๊ฒ์ฒ๋ผ ์์ง ์์ฑ๋ ํ๊ฐ ์์ฃ .
ํ์ง๋ง pulumi up ๋ช ๋ น์ด ์คํ์ด ์๋ฃ๋์, ์๋์ฒ๋ผ ์ธํ๋ผ ์ฝ๋์์ ์ ์ํ ์ด๋ฆ(my-app-queue)์ ์๋ก์ด ํ๊ฐ AWS ์ฝ์ ํ์ด์ง์ ํ์๋ ๊ฒ์ด ๋ณด์ ๋๋ค.
ํด๋น ํ์ ์ด๋ฆ์ ๋๋ฌ์ ์์ธ ์ ๋ณด๋ฅผ ๋ณด๋ฉด, ์ธํ๋ผ ์ฝ๋์์ ์ ์ํ๋ ํ๊ทธ("Environment": "dev", "Project": "MyNewsletterApp")๊ฐ ์ ์ ๋ฐ์๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
5๏ธโฃPulumi๋ก ๋ฐฐํฌํ ์ธํ๋ผ ๋ฆฌ์์ค ์ ๊ฑฐ
์ง๊ธ๊น์ง ์ธํ๋ผ ์ฝ๋ ์์ฑ๊ณผ ๋ฐฐํฌ ๊ณผ์ ์ ์ค์ต์ผ๋ก ์งํํด๋ดค๋๋ฐ์.
์ด๋ ๊ฒ ๋ฐฐํฌํ ๋ฆฌ์์ค๋ฅผ ๋ค์ ์ ๊ฑฐํ๋ ๋ฐฉ๋ฒ๋ ์์๋ณด๊ฒ ์ต๋๋ค.
์ธํ๋ผ ๋ฆฌ์์ค ์ ๊ฑฐ๋ ๋ฐฐํฌ๋งํผ์ด๋ ๊ฐ๋จํฉ๋๋ค.
๋์ผํ ๊ฒฝ๋ก์ ํฐ๋ฏธ๋์์ ์๋์ฒ๋ผ pulumi destroy ๋ช ๋ น์ด๋ฅผ ์คํํ ๋ค์, ๋น๋ฐ๋ฒํธ๋ง ์ ๋ ฅํ๋ฉด ๋๊ฑฐ๋ ์.
pulumi destroy ๋ช ๋ น์ด๋ ํด๋น ์คํ์ ์ธํ๋ผ ๋ฆฌ์์ค๋ฅผ ์์ ํ๊ฒ ์ ๊ฑฐํด์ฃผ์ง๋ง, ์คํ๊ณผ ๊ด๋ จ๋ ์ค์ ๊ณผ ํ์คํ ๋ฆฌ๋ ์ฌ์ ํ ๋จ์์์ต๋๋ค.
์ด์ ์ ์ดํด๋ดค๋ ์ํ ๊ด๋ฆฌ ์์คํ ์ ์คํ๊ณผ ๊ด๋ จ๋ ์ ๋ณด๊ฐ ์ ์ฅ๋์ด ์๋ ๊ฑด๋ฐ์.
๋ง์ฝ ์ด๋ฐ ์คํ๊ณผ ๊ด๋ จ๋ ์ ๋ณด๋ ๋ชจ๋ ์ง์ฐ๊ณ ์ถ๋ค๋ฉด pulumi stack rm ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๋จ, ์ ์ํ ์ ์ด ๋ ๊ฐ์ง ์์ผ๋ ๊ผญ ํ์ธํด์ฃผ์ธ์.
1. pulumi stack rm ๋ช ๋ น์ด ์คํ ์ ์ ๋ฐ๋์ ๋จผ์ pulumi destroy ๋ช ๋ น์ด๋ก ํด๋น ์คํ์ ์ํด ๊ด๋ฆฌ๋๋ ๋ชจ๋ ์ธํ๋ผ ๋ฆฌ์์ค๋ฅผ ์ ๊ฑฐํ ๊ฒ
2. ํ๋ฒ ์ ๊ฑฐ๋ ์คํ ์ ๋ณด๋ ๋ณต๊ตฌ๊ฐ ์ด๋ ค์ฐ๋ฏ๋ก ์ ์คํ ๊ฒ
ํฐ๋ฏธ๋์์ pulumi stack rm ๋ช ๋ น์ด๋ฅผ ์คํํ๋ฉด ์๋์ ๊ฐ์ด ์ ๊ฑฐํ๋ ค๋ ์คํ์ ์ด๋ฆ(dev)์ ์ง์ ํ์ดํํด์ผ ์คํ์ ์ ๊ฑฐํ ์ ์์ต๋๋ค.
์ง๊ธ๊น์ง Pulumi๋ก AWS ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ๋ ๊ณผ์ ์ ์๋์ ํต์ฌ ์ํฌํ๋ก์ฐ๋ฅผ ๋ฐ๋ผ ์งํํ์ต๋๋ค.
1. Pulumi ์ค์น ๋ฐ ๊ณ์ ์ค์
2. ์๋ก์ด Pulumi ํ๋ก์ ํธ ์์ฑ
3. Pulumi ์ธํ๋ผ ๊ด๋ฆฌ ์ฝ๋ ์์ฑ
4. Pulumi๋ก ์ธํ๋ผ ๋ฆฌ์์ค ๋ฐฐํฌ
5. Pulumi๋ก ๋ฐฐํฌํ ์ธํ๋ผ ๋ฆฌ์์ค ์ ๊ฑฐ
๐ญ๋ง์น๋ฉฐ...
์ด๋ฒ ๊ธ์์๋ Pulumi ๋์ ์ ๋์์ด ๋ ์ ์๋๋ก Pulumi ์ค์น๋ถํฐ ๊ณ์ ์ค์ , ์ธํ๋ผ ์ฝ๋ ์์ฑ ๋ฐ ๋ฐฐํฌ๊น์ง ํต์ฌ ๋ด์ฉ์ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ค๋ค๋ดค๋๋ฐ์.
Pulumi์ IaC ๋์ ์ ๊ด์ฌ ์์ผ์ ๋ถ๋ค๊ป ๋์์ด ๋์๊ธธ ๋ฐ๋๋๋ค.
๊ทธ๋ผ, ๋ค์ ์์์ง์์ ๋ณด๋ค ์์ฐจ๊ณ ํฅ๋ฏธ๋ก์ด ๋ด์ฉ์ผ๋ก ์ฐพ์๋ต๊ฒ ์ต๋๋ค.
์ค๋๋ ๊ฐ์ฌํฉ๋๋ค, ๊ตฌ๋ ์๋ ๐บ
๐References
- https://spacelift.io/blog/infrastructure-as-code-toolsfrastructure-as-code-tools
- https://www.pulumi.com/docs/iac/concepts/testing/unit/
์๊ฒฌ์ ๋จ๊ฒจ์ฃผ์ธ์