Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

Study_note

[1주차] T013 테라폼 스터디 본문

Terraform

[1주차] T013 테라폼 스터디

Study_note 2023. 9. 2. 16:40

현재 회사에서도 테라폼을 사용하지만 지금 보다 더 효율적으로 사용하고 싶어 가시다님 스터디를 신청했다

 

---

설치 부분과 기본적인 이론은 넘어간다.

 

 

terraform 명령어

 

terraform init : 테라폼에 코드 스캔을 지시해서 프로바이더 확인 및 플러그인 다운로드

-> 테라폼 파일이 있는 경로에 .terraform 폴더가 생기고, 파일 실행에 필요한 플러그인이 여기 설치된다.

 

terraform plan : 테라폼 빌드 검증 테스트. 실제 변경 전에 수행할 작업 확인

->detailed-exitcode : plan 추가 옵션으로, 파이프라인 설계에서 활용 가능, exitcode가 환경 변수로 구성됨

테라폼 파이프라인을 사용해서 dev,stg 환경을 배포하는데 아래처럼 특정 값이 출력되면 파이프라인을 더욱 활용하기 좋을것 같다.

```bash
# plan 결과를 시스템 코드로 출력
terraform **plan** -detailed-exitcode
...

# 코드 확인 : 0(변경 사항이 없는 성공), 1(오류가 있음), 2(변경 사항이 있는 성공)
**echo $?**
2

# (참고) apply 결과에 적용 시도
terraform apply -auto-approve -detailed-exitcode
```

 

terraform apply : 테라폼 템플릿(tf 파일) 적용시켜 리소스 생성

-> yes 치기 귀찮으면 --auto-approve 옵션 써서 강제 적용.

-> 명령어 입력 후 terraform.tfstate파일 생성

     terraform.tfstate는 JSON 형태로 되어 있는데, 이는 terraform으로 구성된 인프라스터럭처의 현재 상태를 보여준다.

 

terraform destroy : 테라폼 상태 정보 파일을 참조하여 모든 리소스 제거

-> apply처럼 확인 메시지 나오면 yes 입력

 

terraform fmt : format 또는 reformat 줄임 표시로 terraform tmt 명령어로 수행, 테라폼 구성 파일을 표준 형식과 표준 스타일로 적용. 코드 가독성 높인다고 한다.

 

provider

공급자를 aws로 설정, 서울 리전을 선택 하기 위해서 아래와 같이

provider : 클라우드 공급자를 명시해 API와 상호 작용할 수 있습니다.

 

아래 처럼 aws 클라우드뿐만 아니라 helm, kubernetes 등을 설치해서 관리 가능하다

Add on 성향이 있는 3rd party나 오픈 소스는 terraform 통해서 Helm으로 다운 받는다면 훨씬 관리가 용이하다.

provider "aws" {
  region  = var.aws_region
  profile = "hallsholicker"
}

provider "helm" {
  kubernetes {
    host                   = module.eks.cluster_endpoint
    cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
    token                  = data.aws_eks_cluster_auth.eks_cluster.token
  }
}

provider "kubernetes" {
  host                   = module.eks.cluster_endpoint
  cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
  token                  = data.aws_eks_cluster_auth.eks_cluster.token
}

 

리소스

resource "공급자 유형" "이름" {           #  "아래와 같이 공급자_리소스_유형" "이름"  형태로 생성

  설정

}

resource "aws_instance" "example" {
  ami                    = "ami-01d87646ef267ccd7"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.instance.id]
  tags = {
    Name = "terraform-example"
  }
}

 

또한 추후에 또 설명할거지만 간단히 s3 백엔드를 설명하면 아래와 같다

 

백엔드 블록

  • 백엔드 블록의 구성은 테라폼 실행 시 저장되는 **State(상태 파일)**의 저장 위치를 선언한다. (기본: local)
  • 주의할 점은 하나의 백엔드만 허용한다는 점이다.
  • 테라폼은 State의 데이터를 사용해 코드로 관리된 리소스를 탐색하고 추적한다.
  • 작업자 간의 협업을 고려한다면 테라폼으로 생성한 리소스의 상태 저장 파일을 공유할 수 있는 외부 백엔드 저장소가 필요하다.
  • 그리고 State에는 외부로 노출되면 안 되는 패스워드 또는 인증서 정보 같은 민감한 데이터들이 포함될 수 있으므로 State의 접근 제어 및 안전한 관리방안 대책수립이 필요하다.

State 잠금 동작

  • 기본적으로 활성화되는 백엔드local이다.
  • 상태를 작업자의 로컬 환경저장하고 관리하는 방식이다.
  • 이 밖의 다른 백엔드 구성은 동시에 여러 작업자가 접근해 사용할 수 있도록 공유 스토리지 같은 개념을 갖는다.
  • 공유되는 백엔드에 State가 관리되면 테라폼이 실행되는 동안 .terraform.tfstate.lock.info 파일이 생성되면서 해당 State를 동시에 사용하지 못하도록 잠금 처리를 한다.
  • 파일 생성을 확인하고 싶다면 terraform apply를 실행하고 생성되는 잠금 파일을 확인해보자. 잠금 파일 내의 정보는 다음과 같다.

 

정리하면 아래와 같다

개인이 사용할 시 문제가 되지 않지만 팀 단위로 사용을 한다면 문제가 발생한다.

  1. 상태 파일을 저장하는 공유 스토리지 : 인프라 업데이트 시 각 팀원이 동일한 상태 파일에 접근해야 한다.
    즉 상태 파일을 공유 위치에 저장해야 한다.
  2. 상태 파일 잠금 : 2명 이상의 팀원이 동시에 테라폼을 실행하는 경우 상태 파일 업데이트가 충돌할 수 있다.
  3. 상태 파일 격리 : 서비스가 변경될 때, 다른 서비스에 영향을 미치면 안 된다.
    즉 하나의 상태 파일에 모든 정의를 넣는 게 아니라 환경 별로 상태 파일 격리 

이러한 문제점을 해결하기 위해 버전 관리 시스템 대신 테라폼에 내장된 원격 Backend 기능을 사용한다.

( 기본 백앤드는 로컬 디스크에 상태 저장 - 원격 백앤드 공유 저장소에 상태 저장 )

  1. 수동 오류 : apply 명령을 실행할 때마다 해당 백엔드에 상태 파일을 자동으로 로드한다.
  2. 잠금 : apply 명령을 실행하면 테라폼은 자동으로 잠금을 활성화한다.
  3. 시크릿 : S3 버킷의 서버사이드 암호화 기능
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_s3_bucket" "terraform_state" {

  bucket = "terraform-test-kjh-s3"
 # 실수로 s3 삭제하는것을 방지
  lifeccle {
    prevent_destroy = true
  }

}

# state files 버저닝 활성화
resource "aws_s3_bucket_versioning" "enabled" {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = "Enabled"
  }
}

#  state files 암호화 구성
resource "aws_s3_bucket_server_side_encryption_configuration" "default" {
  bucket = aws_s3_bucket.terraform_state.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

# S3 접근 권한 구성
resource "aws_s3_bucket_public_access_block" "public_access" {
  bucket                  = aws_s3_bucket.terraform_state.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "terraform_test-kjh-dynamodb"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

#init 한번 더 해서 다운로드 해준다
terraform {
    backend "s3" { 
      bucket         = "terraform-test-kjh-s3" # s3 bucket 이름
      key            = "terraform/global/terraform.tfstate" # s3 내에서 저장되는 경로를 의미합니다.
      region         = "ap-northeast-2"  
      encrypt        = true
      dynamodb_table = "terraform_test-kjh-dynamodb" # 다이나모db 이름
    }
}

 

###

1주차여서 그런지 기본적인 이론 설명도 많이 해주시고  시간도 길어졌지만 다시 한번 개념을 잡는 기회가 된것 같다.

Comments