데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      한개의 AWS 계정에서 여러 개의 Pulumi project 운영하기

      nabbang 24.09.05
      944 4 0
      DEVOTEE 요약
      Pulumi는 Terraform의 HCL을 극복하여 Python 등 쉬운 언어로 인프라를 관리하는 솔루션입니다. 여러 프로젝트를 운영할 때 각 프로젝트별로 Pulumi 프로젝트를 생성하고 Git에 연결해 관리하며, 기존 리소스와 새로운 리소스를 함께 사용할 수 있습니다. 필요한 리소스를 "컴포넌트"로 작성하여 재활용하고, `pulumi preview` 기능을 사용해 변경사항을 미리 예측할 수 있습니다.

      0. Pulumi란?

      대표적인 IaC 도구인 Terraform의 단점인 HCL(Hashicorp configuration langage) 을 극복하여 쉬운 언어(ex. python)으로 Wrapping 한 솔루션입니다.

      Admin 역할을 하는 Pulumi Console 을 제공하며 Project 단위로 인프라를 관리할 수 있습니다.

      즉, code로 인프라 state를 통한 인프라 status 관리 Terraform 의 기능을 모두 포함하고 있습니다


      1. One AWS Account, Multiple Pulumi Projects

      • 한개의 AWS 계정에서의 프로젝트별 인프라 분리를 위한 여러개의 pulumi project 셋업

      저희는 AWS Organization은 SKT 공용을 사용중이고, {project_id}-dev, {project_id}-stg, {project_id}-prd 로 명명된 세개의 AWS Account 를 부여받아 인프라를 구성하고 있습니다.

      같은 계정 내에서 여러개의 프로젝트를 운영하고 있었으나, "{project_id}-infra" 한 리포지토리 및 Pulumi Project에서 관리중이었는데요.

      두개의 프로젝트일때까지는 괜찮았으나 저희 팀에서 여러개의 프로젝트를 진행하게 되다보니 각 프로젝트끼리 인프라를 분리해야 영향도를 최소화 할수 있다는 판단이 들어 인프라 분리를 고려하였습니다.

      (ex. 한 프로젝트 변경사항이 다른 프로젝트에 영향을 주는 것등을 최소화하기 위함).

      이부분 pulumi community 에 질문해봤는데, 다른 프로젝트의 리소스에 영향을 끼치지 않으면서 같은 aws account와 인프라를 공유하여

      리소스를 여러개의 Project 에서 관리하는 건 흔한 유즈케이스라고 합니다.


      2. Pulumi project 생성

      • pulumi CLI 를 사용하여 신규 프로젝트를 생성합니다.

      # infra 셋팅용 폴더 생성
      mkdir {new_project_id}-infra
      cd {new_project_id}-infra
      # pulumi login & template 으로 위 폴더에서 신규 프로젝트 생성
      pulumi new aws-python
      # 이후 project 와 stack 를 입력
      # project 에는 {new_project_id}-infra, stack(배포환경) 은 dev부터 생성
      # 완료되면 https://app.pulumi.com/{project_id}/projects 에서 확인가능
      
      # git 연결
      git add .
      git commit -m "initial commit"
      git remote add origin ${this_repo}
      git push -u main
      
      # 이후 pulumi console 에서도 git 연결 확인가능

      저는 Project 와 github repo 와 이름을 동일하게 만들고, stack 은 dev, stg, prd 세개 생성하였습니다. 처음엔 일단 dev만 생성하면됩니다.

      자세한 내용은 공식문서 에서 확인 가능합니다.


      3. 전체 아키텍쳐 구성하기

      먼저 전체 아키텍쳐를 그림으로 그려보시고 시작하시면 편합니다.

      그린 그림을 보면서 pulumi resource를 작성해나가는 식으로 작업하였습니다.

      vpc, subnet, igw, tgw 등은 모두 기존의 것을 그대로 사용하고 신규로 생성한것은 두개의 NLB, 한개의 ALB, 한개의 신규 ECS Cluster입니다


      3.1 기존 리소스 가져오기

      관련된 작업을 하다보면, 이미 존재하는 리소스의 ARN 을 사용하는 작업이 있을 수 있습니다.

      예를 들어 subnet 같은 경우에는 굳이 프로젝트 별로 관리할 필요없이 기존에 존재하는 걸 쓰면되기 때문에 아래와 같은식으로 config에 arn을 정의해두고 리소스 생성시에 가져다 쓸 수 있습니다.

      {new_project_id}_api_alb = aws.lb.LoadBalancer(
          f"{{new_project_id}_API}-alb",
          name=f"{{new_project_id}_API}-alb",
          internal=True,
          ip_address_type="ipv4",
          load_balancer_type="application",
          security_groups=[
              {new_project_id}_api_developer_sg.id,
              {new_project_id}_execute_api_sg.id,
          ],
          subnets=[
              config.get_object("subnets")["internal-a"]["id"],
              config.get_object("subnets")["internal-c"]["id"],
          ],
          tags={"servicetitle": "{new_project_id}", "environment": pulumi.get_stack(), "personalinformation": "no"},
      )


      3.2 components 재활용

      위의 전체 아키텍쳐를 통해 기본 네트워크 설정이 완료되면, 실제 서비스를 위한 리소스를 작성합니다.

      이때 "컴포넌트" 를 사용하게 됩니다.

      "컴포넌트" 는 리소스 생성중 재활용하게 되는 코드들을 묶은 커스텀 클래스를 의미합니다.

      예를 들어 ECS 를 이용해서 서빙하고 있는 서버들은 로그그룹, ECR, ECS Service 등을 종합적으로 사용하게 됩니다.

      뿐만 아니라 예를 들어 ECR 에서 ECS Service 로 이미지를 가져올때 사용하는 Role, Policy등 공통적으로 사용하게 되는 것들이 많습니다.

      결국 각각의 네이밍만 다른 비슷한 코드들을 재사용하게 되고, 이를 효율화 하기 위해 컴포넌트를 작성하여 컴포넌트 기반으로 리소스를 생성합니다.

      from typing import Any, Dict, Optional
      
      import pulumi
      
      from .cloudwatch import APILog
      from .iam import APIRole
      from .ec2 import APINetwork
      from .ecs import APIService
      
      
      class API(pulumi.ComponentResource):
          def __init__(self, name: str, variables: Dict[str, Any], opts: Optional[pulumi.ResourceOptions] = None):
              super().__init__("api", name, None, opts)
      
              self.role = APIRole(name, variables=variables, opts=pulumi.ResourceOptions(parent=self))
              self.log = APILog(name, variables=variables, opts=pulumi.ResourceOptions(parent=self))
              self.network = APINetwork(name, variables=variables, opts=pulumi.ResourceOptions(parent=self))
              self.service = APIService(name, variables=variables, opts=pulumi.ResourceOptions(parent=self))

      API 서버에 필요한 role, log, network, 서버 등을 멤버로 API 컴포넌트를 작성하였습니다.

      이 컴포넌트를 이용하여 아래와 같이 실제 리소스를 생성합니다.

      import pulumi
      
      from .components.api import API
      
      SAMPLE_API = "sample-api"
      
      config = pulumi.Config()
      
      sample_api = API(
          SAMPLE_API,
          variables={
              "aws_account": config.get_object("aws_account"),
              "cpu": config.get_object(SAMPLE_API)["cpu"],
              "memory": config.get_object(SAMPLE_API)["memory"],
              "mount_points": [],
              "volumes": [],
              "autoscaling": config.get_object(SAMPLE_API)["autoscaling"],
              "iam_policy": {
                  "Version": "2012-10-17",
                  "Statement": [
                      {
                          "Effect": "Allow",
                          "Action": [
                              "ssmmessages:CreateControlChannel",
                              "ssmmessages:CreateDataChannel",
                              "ssmmessages:OpenControlChannel",
                              "ssmmessages:OpenDataChannel",
                          ],
                          "Resource": "*",
                      },
                      {
                          "Effect": "Allow",
                          "Action": ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"],
                          "Resource": [
                              f"arn:aws:secretsmanager:ap-northeast-2:{config.get_object('aws_account')}:secret:{project_id}/*"
                          ],
                      },
                  ],
              },
          },
      )


      4. main.py

      • 만든 리소스를 import 후 __all__ 에 포함시켜줍니다.

      from resources.sample_api import SAMPLE_API
      
      __all__ = [
          SAMPLE_API,
      ]


      5. 기타

      • workflow 셋업

      • flake8, black 셋업

      • OIDC 관련


      6. Simulation

      aws sso login --profile {project_id}-dev --sso-session skt
      pulumi preview

      terraform plan 과 대응되는 기능이 pulumi preview 입니다.

      코드 변경사항으로 인해 리소스 변경을 미리 예측하고 이상없을지 테스트해볼수 있습니다.


      예시)

      image.png

      pulumi preview 는 공식문서 에 설명이 자세하게 나와있습니다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      nabbang 님의 최신 블로그

      더보기
      동영상 기고하기