엔지니어링

모든 것을 자동화: Terraform + Ansible + Elastic Cloud Enterprise

첫 번째 블로그, Ansible을 이용한 Elastic Cloud Enterprise 설치 자동화에 이어, 이 블로그에서는 Terraform을 이용해 자동화를 클라우드 프로비저닝까지 확장하는 방법을 보여드립니다. 첫 번째 포스팅에서는 Ansible을 사용해 AWS의 가용성 영역 3개에서 Elastic Cloud Enterprise(ECE)를 배포하고 구성하는 방법에 대해 상세하게 설명했습니다. 그러나 기본 EC2 인스턴스의 프로비저닝과 보안 그룹 구성은 모두 수동이었습니다.

이 포스팅에서는 Terraform을 사용하여 그러한 EC2 인스턴스와 보안 그룹 프로비저닝 및 구성을 자동화함으로써 우리의 방법론을 개선하게 됩니다. 또한 이것을 사용하여 지난 번에 빌드한 Ansible 플레이북 설치, 구성, 실행을 자동화해보겠습니다. 자동화는 좋은 것입니다.

그런데 Terraform이란 무엇일까요? 제가 처음에 생각했던 것처럼 스타트렉의 제네시스 디바이스와는 아무 상관이 없습니다. HashiCorp(개발사)에 따르면, 이것은 높은 수준의 구성을 사용해 인프라를 빌드, 변경, 버저닝하는 도구입니다. 코드로서의 인프라, 즉, 코드로 인프라를 관리하는 것입니다. 이것은 여러 가지 이유로 편리하지만, 그 중에서도 가장 편리한 것은 인프라를 실행하고 구성하는 데 필요한 모든 것이 버전 제어와 프로그래밍 방식의 CRUD가 가능한 텍스트 파일에 있다는 점입니다.

이 포스팅이 클라우드 서비스 제공자로 AWS에 중점을 두고 있긴 하지만, Terraform을 사용해 어느 클라우드 서비스 제공자에서도 리소스를 프로비저닝하고 관리할 수 있습니다. 그 주요 클라우드 서비스 제공자 목록과 (확실히) 주요하지 않은 클라우드 서비스 제공자 목록을 확인해 보세요. GCP 사용 예제를 GitHub의 예제 리포지토리에서 보실 수 있습니다.

그리고 마지막으로, 전처럼 이 블로그는 소규모 개념 증명이나 개발 환경에 적합한 ECE 환경을 만들게 되는 기본 데모입니다. 전체 프로덕션 배포에서는 이 설정에서 빠진 인스턴스 그룹, 부하 분산 장치, 그리고 기타 고가용성 구문을 사용해야 합니다. 프로덕션 계획과 배포에 관련된 추가 세부사항은 Elastic Cloud Enterprise 계획 설명서를 참조하세요.

그럼 시작해 볼까요?

작업

다시 한 번 ECE 설명서의 소규모 기본 설치 예제를 따르겠습니다.

  1. Terraform 설치
  2. 인프라 정의
  3. 실행
  4. 즐김

Terraform 설치

HashiCorp 설명서를 따르시면 됩니다. Ansible도 필요한데, 첫 번째 블로그 포스팅에서 설치해보았습니다. 아직 설치하지 않으셨다면, Ansible 설명서를 확인해 보세요. 저의 경우, 다루기 까다로운 맥북프로 키보드로 이렇게 입력했습니다.

> brew install terraform
> brew install ansible

제가 사용한 구성은 Terraform 버전 0.12와도 호환된다는 점에 유의하시는 것이 중요합니다. 좀더 구체적으로 말씀드리자면 저는 0.12.19를 사용했습니다.

인프라 정의

이 작업의 단계는 다음과 같습니다.

  1. 제가 사용한 버전을 이용해 Terraform 구성을 부트스트랩합니다.
  2. 둘러보면서 어떻게 진행되고 있는지 파악합니다.
  3. 여러분에게 고유한 변수들을 설정합니다.

Terraform 구성 부트스트랩

앞서 말씀드렸듯이, Terraform은 구성 파일을 통해 인프라를 프로비저닝하는 방법입니다. 따라서 수많은 구성 파일이 있습니다. 좀더 많은 파일을 신속하게 처리하려면, 리포지토리를 복제하거나 GitHub의 예제 리포지토리에서 파일을 다운로드하세요. 우리가 하려고 하는 모든 작업은 이 파일을 가지고 하게 됩니다.

전처럼, 마우스로 가리켜서 클릭하는 지침을 작성하는 것은 훨씬 더 어렵기 때문에 명령 줄 인터페이스(CLI)를 선호하는 저 같은 사람들을 위해 맞춤화된 단계를 보여드리겠습니다.

단계
  1. 예제 리포지토리를 복제하거나 다운로드합니다.
    > git clone https://github.com/elastic/examples.git
    	
  2. 어디에 저장할 지 파일을 찾아봅니다.
    > cd /workspace/github/elastic/examples
    	
  3. ECE AWS Terraform 예제로 이동합니다.
    > cd Cloud\ Enterprise/Getting\ Started\ Examples/aws/terraform
    	
  4. 텍스트 편집을 조금 할 준비를 합니다.

파일 둘러보기

이제 다음 파일을 보고 계셔야 합니다. 원하시면 파일들을 둘러보세요!

terraform.tfvars.exampleterraform.tfvars로 이름을 바꾼 후에는 여기가 비밀 자료들을 보관하고 우리가 그렇게 원하는 variables.tf의 모든 변수를 다시 정의하는 주요 장소입니다.
variables.tf여러 변수 묶음이며, 훑어보시는 게 좋습니다.
provider.tfAWS로 접속하는 방법을 알려주는 Terraform 구성입니다.
servers.tf원하는 AMI를 찾고, 인스턴스를 배포하고, Ansible이 사용하도록 인스턴스 메타데이터를 캡처하는 Terraform 구성입니다.
networking.tfVPC, 인터넷 게이트웨이, 라우팅 테이블, 서브넷, 보안 그룹 등 수많은 AWS 네트워크 설정을 하는 Terraform 구성입니다.
main.tfAnsible 스크립트를 시작하고 더 중요한 출력의 일부를 수집하는 Terraform 구성입니다.
ansible-install.shECE 역할로 Ansible을 구성하고 실행하기 위해 Terraform이 수정하고 호출하는 스크립트입니다.

변수 설정

이것이 여러분을 위해 작동하도록 하기 위해 몇 가지 다른 변수를 설정해야 합니다(저의 경우와 비교하자면, 저는 이미 잘 작동하도록 해놓았기 때문에 여러분의 경우를 다루려고 합니다).

  • 생성된 모든 AWS 리소스에 태그될 프로젝트 이름
  • 오직 여러분만 기본 인스턴스에 ssh 액세스를 할 수 있도록 하기 위한 여러분의 IP, 누구나 볼 수 있게 개방하고자 하면 0.0.0.0/0로 설정
  • Terraform이 여러 가지를 프로비저닝할 수 있도록 하기 위한 AWS 액세스 자격 증명

AWS 액세스/비밀 키 쌍이 없는 경우, 액세스/비밀 키 쌍 생성을 위한 AWS 설명서를 따르세요.

참고: variables.tf는 EC2 인스턴스로 ssh 액세스하기 위해 사용하는 퍼블릭과 프라이빗 키 파일을 정의합니다. ssh 키가 없는 경우, 구글 검색을 해보시기를 권합니다. DigitalOcean에서 Linux/OSXWindows를 위한 기본 설명을 잘해놓았습니다.

단계
  1. terraform.tfvars.exampleterraform.tfvars로 이름을 바꿉니다.
  2. terraform.tfvars에서 다음과 같이 변경합니다.
    1. 모든 AWS 리소스를 식별하기 위해 사용되는 project_name을 설정합니다.
    2. CIDR 표기법으로 trusted_network를 여러분의 IP로, 또는 선호하는 범위로 설정합니다.
    3. 여러분의 정보로 aws_access_keyaws_secret_key를 설정합니다.
    4. 선택에 따라 aws_region, public_key, 그리고/또는 private_key를 다시 정의합니다.

변경을 요청하지 않는 설정 두 가지는 AMI와 EC2 인스턴스 유형 설정입니다. 여기에는 두 가지 이유가 있지만 주로 시작하는 데 있어 복잡성을 줄이기 위한 것입니다. 지난 번처럼, 우리의 계획은 CentOS 7 AMI에서 i3.xlarge 인스턴스 세 개를 배포하는 것입니다.

  • Terraform이 적절한 AMI를 찾을 수 있도록 하기 위해, 다양한 메타데이터를 제공할 수 있습니다. 이 경우에는 이름 패턴, 소유자 ID(centos.org의 ID), 가상화 유형을 사용했습니다. 이름 패턴과 소유자 ID는 variables.tf에서 구성할 수 있지만 다른 AMI(예를 들어, Ubuntu의 AMI)를 선택하는 경우, remote_user에 대한 다른 값이 필요할 수도 있습니다.
  • 인스턴스 유형을 변경하는 것도 파급력이 있습니다. i3는 Terraform에서 특정한 OS 장치 이름과 구성 설정을 갖는 로컬로 연결된 NVMe 드라이브를 사용합니다. 다른 인스턴스를 사용하고 EBS 볼륨을 연결하는 경우, servers.tf를 변경하여 적절하게 매핑해야 합니다. 자세한 정보는 Terraform 설명서를 참조하세요.

AMI와 EC2 인스턴스 유형에 대해 제가 사용한 설정은 variables.tf에서 볼 수 있습니다.

# AWS 마켓플레이스의 AMI 이름
variable "aws_ami_name" {
  default = "CentOS Linux 7 x86_64 HVM*"
}
# AMI의 소유자
variable "aws_ami_owner" {
  default = "679593333241" # centos.org
}
# 인스턴스로 로그인하여 설치를 수행할 사용자
# 이것은 여러분이 사용하는 AMI에 종속됩니다. 따라서 서로 동기화시켜야 합니다. 예를 들어, Ubuntu AMI는 Ubuntu 사용자를 이용하게 됩니다.
variable "remote_user" {
  default = "centos"
}
# ECE 인스턴스 유형
variable "aws_instance_type" {
  default = "i3.xlarge"
}
# ECE가 사용하게 될 루트가 아닌 볼륨의 장치 이름
# i3 인스턴스의 경우, 이것은 nvme0n1입니다.
# 다른 인스턴스 유형을 사용하는 경우, 이 값은 변경되며, servers.tf의 리소스 정의도 변경해야 할 수 있습니다.
variable "device_name" {
  default="nvme0n1"
}

실행

이제 거의 다 됐습니다. 뭐가 많죠? 기본으로 먼저 실행하고, 시간을 많이 들여 모든 구성 파일을 조사하지 않은 경우, 이 시점에서 그냥 Terraform을 설치하고, 일부 파일을 복사하고, 몇 가지 변수를 설정하기만 하면 될 수도 있습니다. 그럼 그 다음엔 무엇을 해야 할까요? 실행하기만 하면 됩니다!

단계
  1. Terraform을 초기화합니다.
    > terraform init
    	
  2. 우리가 그렇게 노력을 기울여 빌드한 구성을 적용합니다.
    > terraform apply
    	

네, 그렇습니다. 다 됐습니다.

몇 분 후에는 아래에 나와 있는 것과 같이 ECE 관리자 콘솔의 URL과 관리자 비밀번호를 알려주는 출력을 얻어야 합니다.

null_resource.run-ansible (local-exec): TASK [ansible-elastic-cloud-enterprise : debug] ********************************
null_resource.run-ansible (local-exec): ok: [ec2-52-70-7-3.compute-1.amazonaws.com] => {
null_resource.run-ansible (local-exec):     "msg": "Adminconsole is reachable at: https://ec2-35-175-235-131.compute-1.amazonaws.com:12443"
null_resource.run-ansible (local-exec): }
null_resource.run-ansible (local-exec): TASK [ansible-elastic-cloud-enterprise : debug] ********************************
null_resource.run-ansible (local-exec): ok: [ec2-52-70-7-3.compute-1.amazonaws.com] => {
null_resource.run-ansible (local-exec):     "msg": "Adminconsole password is: yI6ClXYNQ5LGiZlBuOm94s8hGV5ispQS24WVfL5fE9q"
null_resource.run-ansible (local-exec): }
null_resource.run-ansible (local-exec): TASK [ansible-elastic-cloud-enterprise : include_tasks] ************************
null_resource.run-ansible (local-exec): skipping: [ec2-52-70-7-3.compute-1.amazonaws.com]
null_resource.run-ansible (local-exec): PLAY RECAP *********************************************************************
null_resource.run-ansible (local-exec): ec2-34-229-205-85.compute-1.amazonaws.com : ok=68   changed=37   unreachable=0    failed=0    skipped=7    rescued=0    ignored=1
null_resource.run-ansible (local-exec): ec2-35-175-235-131.compute-1.amazonaws.com : ok=68   changed=29   unreachable=0    failed=0    skipped=8    rescued=0    ignored=1
null_resource.run-ansible (local-exec): ec2-52-70-7-3.compute-1.amazonaws.com : ok=68   changed=37   unreachable=0    failed=0    skipped=7    rescued=0    ignored=1
null_resource.run-ansible: Creation complete after 16m50s [id=7701810896203834102]
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
Outputs:
ece-instances = [
  [
    "ec2-35-175-235-131.compute-1.amazonaws.com",
    "ec2-34-229-205-85.compute-1.amazonaws.com",
    "ec2-52-70-7-3.compute-1.amazonaws.com",
  ],
]
installed-ece-url = https://ec2-35-175-235-131.compute-1.amazonaws.com:12443

이제 열어서 사용해 보시기 바랍니다. 겁내지 마세요! 잘못되었으면 모두 폐기하고 다음과 같이 새로 만들면 됩니다.

> terraform destroy
> terraform apply

참고: TLS에 사용되는 인증서는 자체 서명되므로, 관리자 콘솔에 액세스하려고 하면 브라우저에 경고가 뜨게 됩니다. 언제나 자체 인증서를 사용하도록 ECE를 구성할 수 있습니다. 설명서에서 더 자세히 읽어보세요.

즐김

  

아마 이번에 우리가 기울인 노력이 지난 번보다 훨씬 적었다는 데에 여러분 모두 동의하시리라 생각합니다. 모든 리소스를 배포하고 구성하고 보안 작업을 하기 위해 AWS 콘솔과 약 38단계까지 가지 않고 모두 관리했습니다(이 새로운 방법은 제가 세어보니 10단계입니다).

이제 가서 마음껏 작업해 보세요. 클라우드는 작고 여러분은 거인처럼 강력합니다! ECE를 가지고 놀고, 클러스터를 활용하고, 업그레이드하고, 크기를 조정해 보세요. 손쉽고 간편한 작업을 마음껏 누리시기 바랍니다.