home..

테라폼 stage, module

HLC Hashicorp Infra Gasida Cloud@net IaC Terraform images/T101

State

State 목적과 의미

탄경

  1. 공유 스토리지 필요성: 여러 팀원이 동일한 테라폼 상태 파일을 사용하기 위해 공유 스토리지가 필요 race condition 을 통한 state 관리
  2. 파일 잠금: 여러 팀원이 동시에 테라폼을 실행할 경우, 상태 파일의 동시 수정으로 인한 충돌이 발생 가능
  3. 환경 격리 isolate state : 개발, 스테이징, 프로덕션과 같은 다양한 환경에서 상태 파일을 격리할 필요

버전 관리 시스템의 한계

  1. 수동 오류: 팀원이 상태 파일을 최신 상태로 유지하지 않으면 문제가 발생할 수 있습니다.
  2. 잠금 미지원: 대부분의 VCS는 상태 파일의 잠금을 지원하지 않습니다.
  3. 시크릿 노출 위험: 상태 파일에는 민감한 정보가 평문으로 저장될 수 있어, 보안 위험이 있습니다.

장점점

테라폼은 이러한 문제를 해결하기 위해 원격 백엔드(AWS S3, Azure Blob Storage 등)를 지원합니다.

  1. 자동 동기화: 테라폼 작업을 실행할 때마다 원격 백엔드에서 자동으로 상태 파일을 불러오고 저장합니다.
  2. 잠금 지원 lock : 원격 백엔드를 사용하면 자동으로 상태 파일의 잠금을 관리할 수 있습니다.
  3. 암호화 지원: 대부분의 원격 백엔드는 데이터 전송 및 저장 시 암호화를 지원합니다.

Untitled

state 동기화 구조는 다음과 같습니다.

  • 테라폼 구성과 State 흐름 : Plan 과 Apply 중 각 리소스에 발생할 수 있는 네 가지 사항, 아래 실행 계획 출력 기호와 의미
기호 의미
+ Create
- Destroy
-/+ Replace
~ Updated in-place

워크스페이스

Terraform의 workspace는 Terraform 설정의 상태를 분리할 수 있는 환경입니다. 여러 workspace를 사용하면 같은 구성을 가진 별도의 환경을 만들 수 있습니다.

예를 들어, 개발(dev), 스테이징(staging), 그리고 프로덕션(production) 환경을 관리해야 하는 경우, 각 환경에 대한 서로 다른 workspace를 생성할 수 있습니다. 이렇게 하면 Terraform 설정은 동일하지만, 각 workspace의 상태는 각각 관리됩니다.

Untitled

주요 기능 및 장점

  • 상태 분리: 각 workspace는 자체 상태 파일을 가지므로 여러 환경에서 동일한 구성을 안전하게 재사용할 수 있습니다.
  • 변수 재사용: 동일한 Terraform 코드를 다른 매개변수와 함께 여러 환경에서 실행할 수 있습니다. 예를 들어, 스테이징 환경에서는 작은 VM 인스턴스를, 프로덕션에서는 큰 VM 인스턴스를 사용할 수 있습니다.
  • 효율적인 리소스 관리: Workspace를 사용하면, 각 환경에 필요한 클라우드 리소스를 따로 관리할 수 있으므로, 리소스를 더 효율적으로 활용할 수 있습니다.

사용법

기본적인 명령어는 다음과 같습니다:

  • 새 workspace 생성: terraform workspace new [workspace_name]
  • workspace 목록 보기: terraform workspace list
  • workspace 전환: terraform workspace select [workspace_name]

여러 workspace를 사용하면, 환경마다 다른 terraform.tfstate 파일이 생성되므로 각각의 환경을 독립적으로 관리할 수 있습니다.

장단점 총정리

  • 장점: 동일한 테라폼 구성으로 다양한 환경의 리소스를 프로비저닝하고 관리할 수 있습니다.
  • 단점: 완벽한 격리가 어렵고, 상태 파일에 대한 접근 권한 관리가 복잡해질 수 있습니다.
  • 유형1 : 신규 리소스 정의 → Apply ⇒ 리소스 생성(처음부터 Terraform 코드로 작업)
    • 실습을 위해서 5.2 디렉터리를 신규 생성 후 열기 → main.tf 파일 생성

        mkdir 5.2 && cd 5.2
      
        locals {
          name = "mytest"
        }
              
        resource "aws_iam_user" "myiamuser1" {
          name = "${local.name}1"
        }
              
        resource "aws_iam_user" "myiamuser2" {
          name = "${local.name}2"
        }
      
    • 실행

        # 
        **terraform init && terraform apply -auto-approve**
        terraform state list
        terraform state show aws_iam_user.myiamuser1
              
        #
        **ls *.tfstate
        cat terraform.tfstate | jq
              
        #
        terraform apply -auto-approve
        ls *.tfstate**
              
        # iam 사용자 리스트 확인
        aws iam list-users | jq
      
  • 유형2 : 실제 리소스 수동 제거 → Apply ⇒ 리소스 생성
    • 실행

        # 실제 리소스 수동 제거
        **aws iam delete-user --user-name mytest1
        aws iam delete-user --user-name mytest2**
        aws iam list-users | jq
              
        # 아래 명령어 실행 결과 차이는? (refresh 유무)
        # 실제 리소스는 제거되었으나 -refrest=false로 인해 변경사항 없으므로 인식
        **terraform plan**
        **terraform plan -refresh=false
        cat terraform.tfstate | jq .serial
              
        #
        terraform apply -auto-approve**
        terraform state list
        **cat terraform.tfstate | jq .serial**
              
        # iam 사용자 리스트 확인
        aws iam list-users | jq
      
  • 유형3 : Apply → Apply - 코드, State, 형상 모두 일치한 경우 ⇒ 변경사항 없음
    • 실행

        **# Serial 값일 동일!
        terraform apply -auto-approve
        cat terraform.tfstate | jq .serial
        terraform apply -auto-approve
        cat terraform.tfstate | jq .serial
        terraform apply -auto-approve
        cat terraform.tfstate | jq .serial**
      
  • 유형4 : 코드에서 일부 리소스 삭제 → Apply ⇒ 리소스 삭제
    • main.tf 파일 수정

        locals {
          name = "mytest"
        }
              
        resource "aws_iam_user" "myiamuser1" {
          name = "${local.name}1"
        }
      
    • 실행

        # 코드 변경으로 인해 user2 삭제
        **terraform apply -auto-approve**
        terraform state list
        terraform state show aws_iam_user.myiamuser1
              
        #
        **ls *.tfstate
        cat terraform.tfstate | jq**
              
        # iam 사용자 리스트 확인
        aws iam list-users | jq
      

유형5 : 리소스만 있으며 코드, State는 없는 경우 → Import 또는 신규코드 작성

  • 유형6 : 실수로 tfstate 파일 삭제 → plan/apply
    • 실행

        # 실수로 tfstate 파일 삭제
        rm -rf terraform.tfstate*
              
        # 아래 두 명령 결과 차이는?
        # Local에 State 파일이 없으므로 두 명령 모두 새로운 리소스 추가(add) 계획
        **terraform plan**
        **terraform plan -refresh=false**
              
        # apply할 경우 어떤 결과 발생?
        # 이미 리소스가 있으므로 Error 발생: EntityAlreadyExists: User with name mytest1 already exists.
        **terraform apply -auto-approve**
        terraform state list
        **cat terraform.tfstate | jq**
              
        # iam 사용자 리스트 확인
        aws iam list-users | jq
              
        # 다음 실습을 위해 iam user 삭제
        **aws iam delete-user --user-name mytest1**
      

      ⇒ 🤔 위 상황에서 복구 하는 방법은? import 등 방법이 있습니다!

모듈

정의와 필요성

  • 테라폼 모듈은 재사용 가능한 테라폼 코드의 집합입니다.
  • 시간이 지날수록 인프라 구성이 복잡해지며, 이를 효과적으로 관리하기 위해 모듈이 필요합니다.

문제점

  • 단일 파일 구조에서 계속 업데이트할 경우 다음과 같은 문제가 발생합니다:
    • 코드를 찾고 수정하기 어려워짐
    • 리소스 간 복잡한 연관 관계로 인해 변경 분석이 어려워짐
    • 비슷한 구성이 여러 환경에서 반복됨
    • 새 프로젝트를 위해 기존 구성을 이해하기 어려움

종류

  • 루트 모듈 (Root Module): 최상위 모듈로, 테라폼이 실행되어 인프라를 프로비저닝하는 모듈
  • 자식 모듈 (Child Module): 루트 모듈에서 호출되는 추가적인 모듈 집합

모듈의 장점

  1. 관리성: 연관된 구성 요소를 묶어 단위별로 쉽게 찾고 업데이트 가능
  2. 캡슐화: 모듈은 논리적으로 묶여 독립적으로 관리되며, 필요한 부분만 외부에 노출
  3. 재사용성: 이미 검증된 모듈을 다른 프로젝트에서도 쉽게 사용 가능
  4. 일관성과 표준화: 모듈을 사용하면 구성의 일관성을 유지하고 복잡성 감

기본원칙

모듈은 테라폼 구성의 라이브러리나 패키지에 해당하는 개념입니다. 복잡한 테라폼 프로젝트를 더 효율적으로 관리할 수 있도록 도와주는 방법으로 사용됩니다.

원칙

  1. 디렉터리 명명 규칙:
    • 모듈의 디렉터리는 terraform-<프로바이더 이름>-<모듈 이름> 형식을 따르는 것을 권장합니다. 이는 Terraform Cloud와 Terraform Enterprise에서도 사용되며, 디렉터리가 테라폼에 특화되어 있고 어떤 프로바이더의 리소스를 사용하고 있는지, 그리고 모듈의 이름이 무엇인지 쉽게 알 수 있게 해줍니다.
  2. 모듈화 구조:
    • 처음부터 모듈화를 고려하여 테라폼 구성을 작성하는 것이 좋습니다. 이렇게 하면 나중에 다른 모듈에서도 이 모듈을 쉽게 호출할 수 있습니다. 또한 리소스들을 논리적으로 그룹화할 수 있습니다.
  3. 독립적 관리:
    • 각 모듈은 독립적으로 관리되어야 하며, 이는 Version Control System(VCS)에서의 관리도 쉽게 해줍니다. 특히 리모트 모듈을 사용하지 않더라도 독립적으로 관리하는 것이 좋습니다.

모듈화 해보기

# terraform init  생성되는 modules.json 파일 확인
tree .terraform
.terraform
├── modules
   └── modules.json
...

## 모듈로 묶여진 리소스는 module이라는 정의를 통해 단순하게 재활용하고 반복 사용할  있다.
## 모듈의 결과 참조 형식은 module.<모듈 이름>.<output 이름>으로 정의된다.
cat .terraform/modules/modules.json | jq
{
  "Modules": [
    {
      "Key": "",
      "Source": "",
      "Dir": "."
    },
    {
      "Key": "mypw1",
      "Source": "../modules/terraform-random-pwgen",
      "Dir": "../modules/terraform-random-pwgen"
    },
    {
      "Key": "mypw2",
      "Source": "../modules/terraform-random-pwgen",
      "Dir": "../modules/terraform-random-pwgen"
    }
  ]
}

[도전과제4] 테라폼 레지스트리에 공개된 모듈을 사용하여 리소스를 배포해본다.

모듈 main.tf

resource "aws_db_instance" "mont" {
  allocated_storage    = var.allocated_storage
  storage_type         = "gp2"
  engine               = "mysql"
  engine_version       = var.engine_version
  instance_class       = var.instance_class
  name                 = var.name
  username             = var.username
  password             = var.password
  parameter_group_name = var.parameter_group_name
  skip_final_snapshot  = var.skip_final_snapshot
  vpc_security_group_ids = var.vpc_security_group_ids
  subnet_ids           = var.subnet_ids
}

모듈 variables.tf

variable "name" {
  description = "The name of the DB instance"
  type        = string
}

variable "username" {
  description = "Username for the master DB user"
  type        = string
}

variable "password" {
  description = "Password for the master DB user"
  type        = string
}

output.tfvars

db_name           = "prod-db"
db_admin_user     = "admin"
db_admin_password = "securepassword"

Untitled

해당구조와 같이 작성한 모듈과 tf파일들로 생성을 진행하였습니다.

Untitled

© 2024 mont kim   •  Powered by Soopr   •  Theme  Moonwalk