thdwoqor / stable-coin-checker

0 stars 0 forks source link

테라폼 코드및 구조를 리팩토링 한다 #6

Closed thdwoqor closed 4 months ago

thdwoqor commented 4 months ago

기존 인프라의 문제

.
├── vpc.tf
├── ec2.tf
├── ...
├── outputs.tf
└── variables.tf

처음에는 하나의 디렉터리에서 모든 리소스를 관리했습니다. 변동성이 다른 리소스를 하나의 디렉터리에서 관리하다 보니 실수가 잦고 불편한 점이 많았습니다. 특정 리소스만 생성하거나 삭제하기 위해 target 옵션을 추가해야 했고, 실수로 target 옵션을 사용하지 않으면 중요한 리소스가 원치 않게 변경되거나 삭제되는 경우가 생겼습니다.

리소스 별로 디렉토리를 분리

├── global
│   ├── vpc/
│   │   ├── main.tf
│   │   └── variables.tf
│   ├── s3/
│   │   ├── main.tf
│   │   └── variables.tf
├── dev/
│   ├── instances/
│   │   ├── main.tf  
│   │   └── variables.tf 
│   ├── codeserise/
│   │   ├── codebuild.tf  
│   │   ├── codedeploy.tf  
│   │   ├── codepipeline.tf  
│   │   └── variables.tf 
├── prod/
│   ├── instances/
│   │   ├── main.tf  
│   │   └── variables.tf 
│   ├── codeserise/
│   │   ├── codebuild.tf  
│   │   ├── codedeploy.tf  
│   │   ├── codepipeline.tf  
│   │   └── variables.tf 

위와 같이 리소스 별로 디렉토리를 분리해서 관리 하는 방식으로 기존 인프라의 문제점을 보완 할 수 있었습니다.

모듈로 재사용 가능한 인프라 생성

각각의 환경(dev, prod) 별로 같은 리소스를 사용하다보니 중복되는 코드가 많이 발생했습니다. 이를 해결하기위해서 환경마다 사용하는 공통된 리소스를 모듈로 만들어서 재사용성을 높히도록 개선 했습니다.

├── global
│   ├── vpc/
│   │   ├── main.tf
│   │   └── variables.tf
│   ├── s3/
│   │   ├── main.tf
│   │   └── variables.tf
├── dev/
│   ├── instances/
│   │   ├── main.tf  
│   │   └── variables.tf 
│   ├── codeserise/
│   │   ├── main.tf  
│   │   └── variables.tf 
├── prod/
│   ├── instances/
│   │   ├── main.tf  
│   │   └── variables.tf 
│   ├── codeserise/
│   │   ├── main.tf  
│   │   └── variables.tf 
├── modules/
│   ├── codeserise/
│   │   ├── codebuild.tf  
│   │   ├── codedeploy.tf  
│   │   ├── codepipeline.tf  
│   │   └── variables.tf 

Terraform 폴더구조 및 사용법 Terraform Proejct Directory Structure Best Practice

결론

리소스별로 디렉토리를 분리하고, 중복된 리소스를 모듈로 관리

thdwoqor commented 4 months ago

리소스 별로 분리된 디렉터리 구조의 문제점

의존 관계 관리의 어려움

리소스마다 의존 관계가 있는 경우, 다른 디렉터리에 있는 변수를 가져오려면 output.tfdata.tf 파일을 생성해야 합니다. 이러한 파일들이 늘어나면서 관리하기가 힘들어졌습니다.

생성과 삭제 순서의 문제

리소스마다 의존 관계가 있는 경우, 하나의 디렉터리 안에 있을 때는 자동으로 의존 관계에 따라 생성되지만, 디렉터리가 분리되어 있는 경우에는 직접 알맞은 순서에 따라 생성 및 삭제를 해야 했습니다. 혼자 개발할 때는 괜찮지만, 협업 시에는 이 순서를 기록하고 팀원들이 모두 인지해야 하는 어려움이 있습니다.

문서화의 어려움

테라폼의 장점 중 하나가 인프라의 문서화입니다. 그러나 디렉터리마다 main.tf 파일을 가지고 있으면 문서가 흩어져 인프라 구조를 파악하기가 힘듭니다.

환경별 하나의 main.tf 사용

├── env                    
│   ├── dev
│   ├── qa
│   ├── stg
│   │   ├── main.tf
│   │   ├── terraform.tfvars
│   │   ├── variables.tf
│   │   └── version.tf
└── modules                   
    │   ├── network
    │   │   ├── main.tf
    │   │   ├── output.tf
    │   │   ├── variables.tf
    │   │   └── versions.tf

large-size-infrastructure-with-terraform DevOps팀의 Terraform 모험

많은 베스트 프랙티스와 예제에서 각 환경별로 하나의 main.tf 파일을 사용하며, 모든 리소스를 main.tf에 작성하고 있습니다. 이렇게 하나의 main.tf 파일로 관리할 경우, 테라폼이 의존 관계에 따라 리소스를 자동으로 생성해주고, main.tf 파일 자체가 하나의 인프라 문서 역할을 하여, 인프라 구조를 명확하게 파악할 수 있습니다.

발생할 수 있는 문제

그렇다면 중요한 리소스가 실수로 지워지는 문제는 어떻게 해결할 수 있을까?

  1. 전체 인프라를 삭제하는것이 아니라면 destroy를 사용하지않고 apply 변경사항을 반영한다.
  2. 데이터베이스와 같이 중요한 리소스는 테라폼이 아닌 수동으로 관리한다.

main.tf의 비대화 문제 해결

모듈을 활용하여 재사용성을 높여 main.tf가 비대해지는 문제를 해결한다.

결론

thdwoqor commented 4 months ago

terraform.tfstate 병합 실패 문제

Terraform 상태 파일(tfstate)을 병합하려고 push 했지만 실패하는 문제가 발생했습니다. 이 문제는 서로 다른 디렉터리에서 terraform.tfstate를 관리하다 보니 serial과 lineage가 달라져서 발생했습니다.

해결

{
  "version": 4,
  "terraform_version": "1.7.5",
  "serial": 28,
  "lineage": "63da9aa5",
  "resources": [
    // terraform.tfstate 기준 파일
    // terraform.tfstate 병합 파일
  ]
}

병합할 tfstate 파일의 resources 섹션을 기준 파일에 수동으로 추가합니다.

resource -> module 변경시 생성 및 삭제 문제

리소스를 module로 바꾸거나 리소스 정보를 변경할때 같은 정보의 리소스를 생성 -> 삭제 하는 문제가 생겼다.

해결

terraform state mv aws_s3_bucket.this module.s3_bucket.aws_s3_bucket.this                                          

Move "aws_s3_bucket.this" to "module.s3_bucket.aws_s3_bucket.this"
Successfully moved 1 object(s).

terraform state mv aws_s3_bucket_public_access_block.this module.s3_bucket.aws_s3_bucket_public_access_block.this  

Move "aws_s3_bucket_public_access_block.this" to "module.s3_bucket.aws_s3_bucket_public_access_block.this"
Successfully moved 1 object(s).

terraform state mv 를 활용해서 리소스 정보를 변경한다.