ABOUT ME

Today
Yesterday
Total
  • Why Terraform
    Terraform 2023. 2. 25. 17:30

    Terraform

    테라폼은 해시코프사가 go언어로 개발한 오픈 소스 도구이다.

    운영체제마다 바이너리 파일이 존재하는데 go코드는 하나의 바이너리 파일로 컴파일되며, 테라폼이라는 명령어로 실행할 수 있다. 이 바이너리를 사용하여 랩톨이나 빌드 서버 또는 다른 컴퓨터에서든 인프라를 배포할 수 있으며 이를 위해 추가 인프라를 생성할 필요가 없다. 정확하게는 Terraform 바이너리가 aws, 에저 같은 공급자를 대신하여 API를 호출하여 리소스를 생성한다. 즉 클라우드 공급자가 제공하는 API 서버를 활용할 뿐만 아니라 AWS에 이미 보유한 API키 같은 인증 메커니즘도 같이 사용한다는 의미이다

     

    테라폼은 어떻게 API를 호출하나?

    테라폼은 생성하려는 인프라 정보가 담겨져 있는 텍스트로 이루어진 테라폼 구성 파일을 생성하여 API를 호출한다

     

    다양한 Iac중 테라폼을 선택하는 기준

    인터넷에서 "infrastructure-as-code"를 검색하면 가장 많이 사용되는 도구 목록을 쉽게 찾을 수 있다.

    Chef, Puppet, Ansible, Pulumi, CloudFormation, Terraform, Heat

    이러한 모든 도구를 사용하여 인프라를 코드로 관리할 수 있지만, 어느 것을 사용해야 하는지 파악하는 것은 쉽지 않다

     

    다른 IAC 도구 대신 Terraform을 선택한 이유에 대한 몇 가지 매우 구체적인 이유들이 있다. 모든 기술 결정과 마찬가지로 트레이드오프와 우선순위의 문제지만, 프로세스를 공유하면 스스로 결정을 내리는 데 도움이 될 수 있다

     

    1. 구성 관리와 프로비저닝

    Chef, Puppet Ansible은 모두 구성 관리 도구이므로 기존 서버에 소프트웨어를 설치하고 관리하도록 설계되었다. CloudFormation Terraform은 프로비저닝 도구이다. 서버 자체(및 로드 밸런서, 데이터베이스, 네트워킹 구성 등과 같은 나머지 인프라)를 프로비저닝하도록 설계되었으며 이러한 서버 구성 작업은 다른 도구에 맡긴다.

     

    둘을 명확하게 구분하기는 애매하다

    구성 관리 도구도 일반적으로 어느 정도의 프로비저닝을 수행할 수 있고, 테라폼을 사용하여 구성 스크립트를 실행하는 것처럼 프로비전 도구도 어느 정도의 구성을 수행할 수 있다

     

    하지만 Docker를 사용하면 서버에 필요한 모든 소프트웨어가 이미 설치 및 구성되어 있다. Dockerfile에서 이미지를 만들었다면 이제 이미지를 실행할 인프라를 프로비저닝해야한다. 프로비저닝 하려면 일반적으로 Terraform과 같은 프로비전 도구가 구성 관리 도구보다 더 적합하다.

     

    서버 템플릿 도구를 사용하지 않는 경우 구성 관리 및 프로비저닝 도구를 함께 사용하는

    것이 좋다. 예를 들어 Terraform을 사용하여 서버를 프로비저닝하고 Ansible을 사용하여 각 서버를 구성하는 것이다.

     

    주요 구성 관리 도구 중 Chef,Puppet이 프로비저닝 지원을 점진적으로 포함시키면서, 구성 관리와 프로비저닝은 점점 구분하기 애매해지고 있다

     

    2. 변경 가능한 인프라와 변경 불가능한 인프라

    Chef, Ansible과 같은 구성 관리 도구는 일반적으로 가변 인프라를 사용한다.

    가변 인프라는 시간이 지나면서 점점 더 많은 업데이트를 적용하고, 각 서버는 고유한 변경 기록을 작성하게 된다. 결과적으로 각 서버는 다른 모든 서버와 약간씩 다르기 때문에 진단 및 재현하기 어려운 미묘한 구성 버그(configuration drift)가 발생한다. 자동화된 테스트를 사용하더라도 이러한 버그를 잡기는 쉽지 않다. 테스트 서버에서는 구성 관리 변경이 제대로 작동할 수 있지만, 프로덕션 서버에는 테스트 환경에 반영되지 않은 변경 사항이 몇 개월 동안 누적되어 있기 때문에 동일한 변경 사항이 프로덕션 서버에서 다르게 작동할 수 있다.

     

    Terraform과 같은 프로비저닝 도구를 사용하여 Docker에서 생성된 머신 이미지를 배포하는 경우 대부분의 변경은 완전히 새로운 서버를 배포하는 것과 같다.

     

    배포 시 새로운 서버에서 불변의 이미지를 사용하기 때문에 이 접근 방식은 configuration drift의 가능성을 줄이고 각 서버에서 어떤 소프트웨어가 실행되고 있는지 정확히 알 수 있게 한다. 또한 이전 버전으로 쉽게 복원할 수 있으며, 테스트 환경에서 테스트를 통과한 이미지는 운영환경에도 동일하게 배포되므로 자동 테스트의 효율성을 높일 수 있다.

     

    물론 구성 관리 도구가 변경 불가능한 배포를 수행할 수는 있지만 적절한 접근 방법이 아니며, 프로비저닝 도구를 사용하는 자연스러운 방법입니다.

     

    불변 인프라를 사용할 경우에도 자체 단점이 있다

    서버 템플릿에서 이미지를 다시 빌드하고 사소한 변경을 할 때조차 서버를 템플릿에서 이미지를 재구성하고 모든 서버를 재배포하기 위해 시간이 오래 걸릴 수 있다.

    또한 불변성은 실제로 이미지를 실행할 때까지만 지속된다. 서버가 가동되고 실행되면 하드 드라이브를 변경하기 시작하고 어느 정도의 구성 드리프트가 발생한다.(자주 배포하는 경우 완화됨)

     

    3. 절차적 vs 선언적

    Ansible은 원하는 최종 상태를 달성하는 방법을 단계별로 지정하는 절차적 스타일을 권장한다. Terraform은 원하는 최종 상태를 지정하는 선언적 방식의 코드를 권장한다.

     

    처음 AnsibleTerraform으로 동일한 작업을 실행하면 비슷한 결과가 나오지만 코드를 변경할때 차이점이 생긴다

     

    트래픽이 증가했고 서버 수를 15개로 늘리고 싶다고 가정할 때,

    Ansible을 사용하면 이전에 작성한 절차 코드가 더 이상 유용하지 않다. 즉 서버 수를 15개로 업데이트하고 해당 코드를 다시 실행하면 15개의 새 서버가 배포되어 총 25개를 배포한다 따라서 15개로 업데이트 하려면 이미 배포된 항목을 확인하고 완전히 새로운 절차 스크립트를 작성하여 5개의 새 서버를 추가해야 한다.

     

    선언적 코드를 사용하면 원하는 최종 상태를 선언하고 Terraform이 해당 최종 상태에 도달하는 방법을 파악하기 때문에 Terraform은 과거에 생성한 모든 상태도 인식한다. 따라서 서버를 5개 더 배포하려면 동일한 Terraform 구성으로 돌아가서 개수를 10에서 15로 업데이트하기만 하면 된다.

     

    Ansible을 사용하면 새 인스턴스를 배포하기 전에 태그를 사용하여 기존 EC2 인스턴스를 검색할 수 있지만, 각 리소스의 과거 내용을 기반으로 관리하며 모든 단일 리소스에 대해 로직을 수동으로 파악해야 하며, 수동으로 로직으로 파악하는 것은 쉬운 일이 아니다. 이는 절차적 IaC 도구의 두 가지 주요 문제를 강조한다.

     

    절차 코드는 인프라의 마지막 상태 정보를 기록하지 않는다

    Ansible 템플릿을 읽는 것만으로는 무엇이 배포되었는지 파악하기에 쉽지 않다. 또한 해당 템플릿이 적용된 순서 를 알아야 한다. Ansible에 대해 추론하려면 지금까지 발생한 모든 변경 사항의 전체 기록을 알아야 한다.

     

    절차 코드는 재사용성을 제한한다.

    인프라의 현재 상태를 수동으로 고려해야 하기 때문에 절차적 코드의 재사용 가능성은 제한된다. 인프라의 상태는 지속적으로 변경되며 결과적으로 절차적 코드 방식는 시간이 지남에 따라 커지고 복잡해지는 경향이 있다.

     

    Terraform의 선언적 접근 방식을 사용하면 코드가 항상 인프라의 최신 상태를 나타낸다. 현재 배포된 항목과 구성 방법을 한 눈에 확인할 수 있으며. 현재 상태를 수동으로 설명할 필요가 없기 때문에 재사용 가능한 코드를 쉽게 만들 수 있다.

     

    물론 선억적 방식은 표현력이 제한되어 있다는 단점이 있다

    if, 반복문 등 로직을 수행하는 능력이 제한되어 있어 재사용 가능한 코드틀 만들기 까다로울 수도 있다 하지만 Terraform은 여러 강력한(변수, 모듈 등) 기본 요소를 제공하기 떄문에 선언적 언어임에도 깔끔하고 구성이 자유로운 모듈식 코드를 작성할 수 있다

     

    4. 마스터 vs 마스터리스

    기본적으로 Chef Puppet에서는 인프라 상태를 저장하고 업데이트를 배포하기 위해 마스터 서버를 실행해야 한다. 인프라를 업데이트하려면 Command-line과 같은 도구를 사용하여 마스터 서버에 새 명령을 실행하고 마스터 서버는 업데이트를 다른 모든 서버에 푸시하거나. 서버들이 주기적으로 마스터 서버에서 최신 업데이트를 가져온다.

     

    마스터 서버는 몇 가지 이점을 제공한다.

    첫째, 인프라의 상태를 보고 관리할 수 있는 단일 중앙 역할을 한다. 많은 구성 관리 도구는 마스터 서버에 웹 인터페이스를 제공하여 상황을 쉽게 확인할 수 있다

    둘째, 일부 마스터 서버는 백그라운드에서 지속적으로 실행되어, 구성의 일관성을 적용할 수 있다. 이렇게 하면 누군가 서버를 수동으로 변경하면 마스터 서버가 해당 변경 사항을 되돌려 구성 드리프트를 방지할 수 있다.

     

    그러나 마스터 서버를 실행해야 하는 데는 몇 가지 단점이 있다.

     

    추가 인프라

    마스터를 실행하기 위해 추가 서버 또는 추가 서버 클러스터(고가용성 및 확장성을 위해)를 배포해야 한다.

     

    유지

    마스터 서버를 유지 관리, 업그레이드, 백업, 모니터링 및 확장해야 한다.

     

    보안

    클라이언트가 마스터 서버와 통신하는 방법과 마스터 서버가 다른 모든 서버와 통신하는 방법을 제공해야 한다. 이는 일반적으로 추가 포트를 열고 추가 인증 시스템을 구성하는 것을 의미하며, 서버가 공격당할 가능성을 높인다

     

    Ansible, Terraform은 기본적으로 마스터리스이다. 더 정확하게 말하면 일부는 마스터 서버에 의존하지만 이미 사용 중인 인프라의 일부이며 관리해야 하는 추가 부분이 아니다.

    예를 들어 Terraform은 클라우드 공급자의 API를 사용하여 동작한다. 어떤 의미에서는 API서버가 마스터 서버가 될 수 있지만 추가 인프라나 추가 인증 메커니즘이 필요하지 않은며 사용자의 API 키를 사용하면 된다. 그렇기 때문에 어떤 추가적인 인프라나 추가 인증 메커니즘을 관리 할 필요가 없다

     

    5. 에이전트 대 에이전트리스

    Chef Puppet 에서는 구성하려는 각 서버에 에이전트 소프트웨어를 설치해야 한다. 에이전트는 일반적으로 각 서버의 백그라운드에서 실행되며 최신 구성 관리 업데이트 설치를 담당한다.

     

    구성요소 간 관계가 복잡해지면 인프라에 다양한 장애가 발생할 수 있다 많은 구성 요서들 중 어디에서 버그가 발생하는지 계속해서 모니터링을 해야한다

     

    Ansible, CloudFormation는 추가 에이전트를 설치할 필요가 없다. 또는 더 정확하게 말하면 일부는 에이전트가 필요하지만 일반적으로 사용 중인 인프라의 일부로 이미 설치되어 있다. 예를 들어 AWS, Azure, Google Cloud 및 기타 모든 클라우드 공급자는 각 물리적 서버에서 에이전트 소프트웨어를 설치, 관리 및 인증한다. Terraform 사용자는 명령만 내리면 클라우드 공급자의 에이전트가 모든 서버에서 명령을 실행한다. Ansible을 사용하면 서버는 SSH 데몬을 실행해야 하는데 SSH 대몬은 서버에서 실행된다

     

    6.  대규모 커뮤니티 대 소규모 커뮤니티

    기술을 선택할 때마다 커뮤니티도 고려해야한다. 대부분의 경우 프로젝트 주변의 생태계는 기술 자체의 고유한 품질보다 경험에 더 큰 영향을 줄 수 있다. 커뮤니티는 프로젝트에 참여하는 사람 수, 사용 가능한 플러그인, 통합 및 확장 프로그램 수, 정보를 얻을 수 있는 방법 등도움을 줄 누군가를 쉽게 찾을 수 있다.

     

    커뮤니티 간의 정확한 비교는 어렵지만 온라인 검색을 통해 몇 가지 추세를 파악할 수 있다.

    출처: https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c

     

     

    7. 성숙한 기술

    기술을 선택할 때 고려해야 할 또 다른 주요 요소는 성숙도이다.

     

    테라폼은 2014년도의 출시 되어 Iac 도구들 중 가장 최근에 나왔다. 여전히 1.0.0이전의 버전이므로 안정적이지 않고 이전 버전과 호환되는 API를 보장하지 않으며, 사소한 것들이기는 해도 버그가 존재할 수 있다. 이것은 테라폼의 가장 큰 약점이다

     

    하지만 개인적인 생각으로는 출시 기간과 낮은 버전으로 성숙도를 판단하는 것은 적절치 않다 생각한다. 물론 낮은 버전은 안정적이지 않을 수 있지만, 다른 Iac와 비교 할 경우 낮은 성숙도를 갖지는 않는다. 오히려 높은 버전을 가졌음에도 Terraform보다 낮은 성숙도를 보여주는 도구(Pulumi)들도 있다.

     

     

    8. 여러 도구를 함께 사용

    앞서 IaC 도구를 비교했지만 실제로는 인프라를 구축하기 위해 여러 도구를 사용해야 할 가능성이 높다. 각 도구에는 장단점이 있으므로 적절한 도구를 선택하는 것이 중요하다.

     

    다음은 자주 사용하는 일반적인 코드형 인프라 도구 조합이다.

     

    프로비저닝 및 구성 관리

    프로비저닝 및 서버 템플릿

    프로비저닝 + 서버 템플릿 + 오케스트레이션

     

    프로비저닝과 구성 관리

    Terraform Ansible을 같이 사용할 수 있다. Terraform을 사용하여 VPC(Private Cloud), 서브넷, 라우팅 테이블 같은 네트워크 토폴로지, 데이터 저장소(MySQL, Redis), 로드 밸런서 및 서버를 포함한 모든 기본 인프라를 배포한고, Ansible을 사용하여 해당 서버 위에 앱을 배포한다.

    출처: https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c

     

    이와 같은 방법은 처음에 접근하기 쉬운 방법이다. TerraformAnsible은 클라이언트 전용 응용 프로그램으로써 추가로 실행할 인프라가 없고 함께 작동시킬 수 있는 여러 갖 방법이 있기 때문이다. Terraform이 서버에 특별한 태그를 추가하고 Ansible은 그렇게 추가한 태그ㅡ를 이용하여 서버를 식별하고 구성을 진행한다. 그러나 일반적으로 Ansible을 변경 가능한 형태로 사용하면 절차적인 요소가 많은 코드를 작성해야 하므로 인프라 및 조직이 성장함에 따라 유지 관리가 어려워질 수 있다는 단점이 있다.

     

     

    프로비저닝 및 서버 템플릿

    TerraformPacker를 같이 사용한다. Packer를 사용하여 앱을 VM 이미지로 패키징한다. Terraform을 사용하여 VM 이미지를 배포하고 네트워크 토폴로지 데이터 저장소및 로드 밸런서를 같이 배포한다

    출처: https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c

     

    둘 다 클라이언트 전용 프로그램이므로 추가적으로 구성할 인프라가 없기 떄문에 초반에 쉽게 접근할 수 있다. 불변 인프라 접근 방식이므로 유지 관리가 더 쉬워진다. 하지만 두 가지 주요 단점이 있다.

    첫째, VM을 구축하고 배포하는 데 시간이 오래 걸리므로 반복 속도가 느려진다.

    둘째, Terraform으로 구현할 수 있는 배포 전략 블루-그린 배포를 구현할 수 없으며, 제한되어 있다. 복잡한 배포 스크립트를 많이 사용하거나, 오케스트레이션 도구를 사용해야한다.

     

    프로비저닝 + 서버 템플릿 + 오케스트레이션

    Terraform, Packer, Docker Kubernetes를 함께 사용한다. Packer를 사용하여 Docker Kubernetes 에이전트가 설치된 VM 이미지를 만든다. Terraform을 사용하여 VM 이미지를 실행하는 서버 클러스터와 네트워크 토폴로지, 데이터 저장소 및 로드밸런서를 포함한 나머지 인프라를 배포한다. 마지막으로 서버가 구동되면 컨테이너로 된 애플리케이션을 쿠버네티스 같은 오케스트레이션 도구엣 실행한다.

    출처: https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c

    이 방법의 장점은 Docker 이미지가 상당히 빠르게 빌드되고 로컬 컴퓨터에서 실행 및 테스트할 수 있으며 다양한 배포 전략, 자동 복구, 자동 확장을 포함하여 Kubernetes의 모든 내장 기능을 활용할 수 있다는 점이다. 단점은 추가적인 인프라가 필요하므로 운영이 복잡해진다. (Kubernetes 클러스터는 배포 및 운영이 어렵고 비용이 많이 들지만, 현재 대부분의 주요 클라우드 공급자는 관리형 Kubernetes 서비스를 제공하고 있다.) 이는 운영의 일부를 신경 쓰지 않아도 된다는 의미이다. Terraform, Packer, Docker Kubernetes등 추가적인 계층을 학습, 관리 및 디버깅해야한다는 단점일수도 잇다.

     

    결론

    정리하면 아래 표와 같이 정리할 수 있다. 이 표는 다양한 Iac 도구가 사용되는 기본 또는 가장 일반적인 방법을 보여준다.

    https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c

     

Designed by Tistory.