3 minute read

약 8주간 가시다 님과 함께한 테라폼 스터디가 마무리 되었다.

졸업 과제로 무엇을 할까 고민하다가, 개인적으로 관심이 있는 주제인 ‘Chapter 8. Production-Grade Terraform Code’을 실습 하면서,
스터디에서 이뤄졌던 주요 주제/실습들을 포함하고자 하였다.

프로젝트 관련 GIT Repository

프로젝트 목표

프로덕션 수준의 테라폼 코드 활용을 위해선 아래와 같은 항목들이 포함되어 있어야 한다고 생각한다.

  1. tfstate 관리를 위한 별도의 remote 저장소 및 Lock 기능
    • tfstate 저장을 위한 S3 버킷, Locking을 위한 DynamoDB 사용하여 구현
    • Human Error 방지
      • 각 팀원의 local 환경에 tfstate 파일이 보관되어있으면, 실제 환경과 갭이 있을 가능성 있음 > 원격 저장소를 통한 동일한 상태 보장
      • Lock 기능 없이 여러 팀원이 apply 적용시 tfstate 깨질 가능성 O
  2. 상태 파일간 격리
    • 각 tf파일들을 디렉토리 단위로 격리하여 구현
    • 격리를 통해 개선되는 것들
      • 속도 개선: 구성 파일 및 상태파일을 분리함으로써 plan 및 apply 시간 감소
      • 장애 범위 감소: 관리중인 상태파일에 이상이 생겼을때, 파급력 약화
  3. 문법적 고도화 (variable, count, for_each, etc…)
    • 리소스연계, 변수, 반복문(count,for_each), 조건문(conditionals) 활용
    • 가독성
      • 리소스 연계 및 변수를 활용하여 하드코딩 된 부분을 제거 > 가독성 및 사용성 증가
        • “subnet-00326f4abde878d0c” 보다는 “aws_subnet.pub2” 식으로
        • 하드코딩된 부분이 있으면 리소스 삭제등에도 영향을 줄 수 있음
      • 반복문, 조건문 활용 > 불필요하게 반복되는 부분 감소
        • 구성파일의 코드 수를 줄인다고 해서 apply 속도가 개선되거나 하진 않음
        • 그래도 전체 코드 수를 감소시키면 관리시 편함
  4. 민감정보 관리
    • parameterm store 및 암호 자동생성을 통해 노출 방지
    • 구성 파일 내부에 민감 정보를 저장하는것은 위험함.
      • Access Key, DB passwd, SSH키, 등등
      • 별도로 노출되지않도록 관리 필요
  5. 모듈화
    • network, alb, ec2, rds 모듈 작성 및 사용
    • 신뢰성, 재사용성
      • 비슷한 환경을 재구축할때 용이하게 사용 가능
      • 모듈로 생성된 리소스들은 같은 명명규칙, 설정 값을 공유한다는 확신

아쉬운 점

touchthewall

막힌 길인게 보여도, 굳이 끝까지 가서 벽을 찍어보고 싶은 마음

구상을 하면서도, 이게 맞는 건지 확신이 들지 않는 부분들이 다수 있었다.
해보지 않고 고민하는건 한계가 있다고 생각하기 때문에 끝까지 진행하긴 했지만,
여전히 활용이 고민되는 부분이 많다

  1. 구성 파일 간 격리 수준
    • 아무리 생각해봐도 어느정도가 적정수준일 지 모르겠음
    • 빠른 적용시간, 충격반원 감소 vs 구성파일간 쉬운 연계, 전체 리소스 변경사항 감지
      • 각자의 장단점은 명확함. 장점은 위에서 언급하였음
      • 과연 빨라지는가? tfp/tfa 한번으로 생성할 수 있는것들을 계속 cd ../.. 하면서 생성할 때마다 드는 의문
      • 작성이 쉬워지는가? aws_security_group.ec2.id로 간단히 연계할 수 있는 부분을 별도 output/data 블록을 사용하여 전달
      • 파악이 용이해지는가? 디렉토리가 많아지고 depth가 깊어질 수록 난해해짐, 수동제어로 변경사항 발생하여도 plan/apply전까지는 감지 불가
  2. auto.tfvars 활용
    • variable 블록대신 key=value 형태로 input variable을 간편하게 관리할 수 있을것이라고 생각
    • 입력값이 많아질수록 그렇게 간편한것 아닌것같음
    • (중요) 리소스 연계, variable, local 등 사용 불가, 명시적 데이터(num,string,list,etc)만 입력 가능
    • 변수 생성 및 적용시 main.tf 및 variable.tf 뿐만아니라 auto.tfvars 수정해야함 > 피곤해짐
    • 앞으로는 안씀

Project Structure

.
├── modules
│   ├── alb
│   │   ├── alb-mod-main.tf
│   │   ├── alb-mod-output.tf
│   │   └── alb-mod-variable.tf
│   ├── ec2
│   │   ├── ec2-mod-main.tf
│   │   ├── ec2-mod-output.tf
│   │   └── ec2-mod-variable.tf
│   ├── network
│   │   ├── nw-main.tf
│   │   ├── nw-output.tf
│   │   └── nw-variable.tf
│   └── rds
│       ├── rds-main.tf
│       ├── rds-output.tf
│       └── rds-variable.tf
├── project_aaa
│   ├── dev
│   │   ├── 00.s3_backend
│   │   │   ├── s3.tf
│   │   ├── 01.network
│   │   │   ├── network.auto.tfvars
│   │   │   ├── network.tf
│   │   │   ├── network-variable.tf
│   │   ├── 02.database
│   │   │   ├── rds.auto.tfvars
│   │   │   ├── rds.tf
│   │   │   └── rds-variable.tf
│   │   └── 03.apps
│   │       ├── app1
│   │       │   ├── app1-data.tf
│   │       │   ├── app1-main.tf
│   │       │   ├── app1-variable.auto.tfvars
│   │       │   └── app1-variable.tf
│   │       └── app2
│   │           └── main(wip).tf
│   └── prod
├── project_bbb
└── project_ccc

디렉토리별 상세 설명

/

최상위 디렉토리

각 환경에서 사용할 modules 디렉토리와,
project_aaa,bbb,ccc 식으로 큰 프로젝트 단위별 디렉토리 생성

/modules

모듈 디렉토리

network(vpc,subnet,등) / alb / ec2 / rds 모듈 생성
필요시 iam, ecs, 등 필요한 모듈 생성 및 추가 가능

/project_xxx

프로젝트 디렉토리

관리 범위에 따라 묶인 디렉토리
내부에 환경별로 dev와 prod로 한번 더 나뉨

각 환경별로 순서대록 실행하여 환경 구성할 수 있도록 번호부여
(S3생성 > VPC 생성 > RDS 생성 > Application 환경 생성)

필요에 따라 kms, route53, iam 등을 추가할 수 있을듯함


프로젝트 결과

  1. 원격 저장소
    • AAA는 aaa-network로 수정필요
    • 작업별로 분리된 state 파일
      • 다른 팀원이 aaa 프로젝트의 app1과 app2를 lock 방해없이 각자 수정할수 있을지도..? > 확인필요 trf2-1
  2. 문법적 고도화
    • EC2 생성에 있어서, 다수의 EC2를 2개의 AZ1/AZ3에 교차생성하고자함
      • for_each = {1=AZ1, 2=AZ3, 3=AZ1, 4=AZ3, …}
      • 아닌듯함
    • 내장 함수들과 연산자를 사용하여 해결
      • 숫자(3, num)를 문자열 리스트([“1”,”2”,”3”], a set of strings) 로 변환
        • for_each = toset(formatlist("%d", range(1, var.amount + 1)))
      • 2게의 서브넷을 입력한 뒤, 나머지를 활용해 교차생성
        • subnet_id = var.subnet_id[(each.key + 1) % 2]
  3. 민감정보 관리
    • AWS Access Key를 구성파일에 명시하는 대신, aws cli로 구성하여 사용
    • DB passwd를 구성파일에 명시하는 대신, 랜덤 비밀번호를 생성하여 사용
      • output으로 필요시 조회가능 trf2-2
  4. 접속 확인
    • ALB의 DNS로 접근하여 생성 결과 확인 trf2-3

Categories:

Updated:

Leave a comment