테라 폼 구성을 테스트하는 방법?


37

당신은이 있다면 Terraform의 방법은 지속적인 통합 / 연속 배달 파이프 라인의 일부로 실행 될 수있는 구성의 주위에 테스트를 작성합니다, 복잡성의 중간 정도를 가지고 구성을?

예를 들어, 다음과 같은 원하는 상태를 지정하는 다중 클라우드 구성이있을 수 있습니다.

  • Azure에서 Docker를 호스팅하는 Azure Container Services
  • Azure Blob 저장소
  • SQL Azure
  • AWS에서 Docker를 호스팅하는 EC2 컨테이너 서비스
  • 아마존 S3 스토리지 서비스
  • Amazon RDS SQL Server 데이터베이스

잠재적으로 terraform apply위의 내용을 처음부터 만들거나 부분적으로 배포 된 상태에서 위의 원하는 상태로 전환 할 수 있습니다.

Terraform은 작업 계획 단계와 실제로 대상 아키텍처를 변경 하는 응용 프로그램 단계 로 작업을 분할한다는 것을 알고 있습니다. 실행 계획에 대한 테스트를 작성하는 데 사용할 수 있습니까? 작성하는 데 도움이되는 프레임 워크가 있습니까?



실제로 흥미롭고, 합당하게 대답 할 수 있습니다.
Richard Slater

저는 직접 테라
포름을

답변:


20

현재 Terraform에 통합 된 완벽한 솔루션은 없지만 별도의 프로그래밍 언어로 테스트를 작성하는 데 도움이 될 수있는 몇 가지 빌딩 블록이 있습니다.

Terraform은 원칙적으로 외부 프로그램에서 Terraform이 생성 한 것에 대한 특정 데이터를 추출하는 데 사용할 수있는 JSON 형식의 상태 파일을 생성합니다. 이 형식은 아직 공식적으로 안정적인 것으로 간주되지는 않지만 실제로 사람들이 Terraform을 업그레이드 할 때 조정해야 할 수도 있음을 인정하여 사람들이 성공적으로 통합 할 수있을 정도로 자주 변경되지 않습니다.

여기서 어떤 전략이 적합한 지 정확히 테스트하려는 대상에 따라 달라집니다. 예를 들면 다음과 같습니다.

  • 가상 서버를 가동하는 환경에서 Serverspec 과 같은 도구를 사용하여 이러한 서버의 관점에서 테스트를 실행할 수 있습니다. 이것은 대역 외 프로세스를 사용하여 Terraform과 별도로 실행하거나 Terraform의 일부로 remote-execprovisioner를 사용하여 적용 할 수 있습니다 . 이를 통해 "서버가 데이터베이스에 도달 할 수 있습니까?"와 같은 질문을 확인할 수 있지만 "인스턴스 보안 그룹이 충분히 제한적입니까?"와 같은 질문에는 적합하지 않습니다. 인스턴스 자체 외부에서 데이터에 액세스해야하는지 강력하게 확인하기 때문입니다.

  • 그것은 기존의 테스트 프레임 워크 사용하여 쓰기 시험 (예 : 루비 RSpec에 등을하는 것이 가능 unittestTerraform 상태 파일에서 해당 리소스 ID 또는 주소를 수집 한 후 자원과 어설 그것에 대해 데이터를 검색하기 위해 해당 플랫폼의 SDK를 사용하여 파이썬 등) 그들은 예상대로 설정됩니다. 이는 테스트중인 인프라 외부 의 호스트 관점에서 테스트를 실행하는보다 일반적인 형태의 이전 아이디어 이므로 어설 션을 작성하기 위해 광범위한 데이터 세트를 수집 할 수 있습니다.

  • 좀 더 겸손한 요구를 위해 Terraform 상태는 실제의 정확한 표현 (많은 경우에 유효한 가정)임을 신뢰하고 간단하게 직접 주장 할 수 있습니다. 이는 비용 할당을 위해 올바른 리소스 태깅 체계를 따르는 지 확인하는 것과 같이 단순한 "보풀이없는"경우에 가장 적합합니다.

관련된 Terraform Github 이슈 에서 이것에 대한 더 많은 논의가 있습니다.

최신 버전의 Terraform에서는 장난감이 아닌 응용 프로그램에 대해 원격 백엔드를 사용하는 것이 좋지만 상태 데이터를 로컬 디스크에서 직접 사용할 수는 없습니다. 그러나 terraform state pullJSON 형식의 상태 데이터를 stdout에 인쇄하여 호출 프로그램에서 캡처하고 구문 분석 할 수있는 명령을 사용하여 원격 백엔드에서 스냅 샷의 스냅 샷을 검색 할 수 있습니다.


12

이 질문에 대한 업데이트로 이제 프로덕션 환경을 중단하지 않고 Terraform 구성 파일을 테스트 할 수있는 Kitchen-Terraform 이 있습니다. 이 저장소에는 다양한 Terraform 제공 업체에 대한 몇 가지 예제도 포함되어 있습니다.


12

최근 인프라 코드 테스트를 위해 스위스 군용 칼인 Terratest를 오픈 소스로 공개했습니다 .

현재는 배포, 유효성 검사 및 배포 취소를 통해 모든 인프라 코드를 수동으로 테스트하고있을 것입니다. Terratest는이 프로세스를 자동화하는 데 도움이됩니다.

  1. Go에서 테스트를 작성하십시오.
  2. Terratest의 도우미를 사용하여 실제 IaC 도구 (예 : Terraform, Packer 등)를 실행하여 실제 환경 (예 : AWS)에 실제 인프라 (예 : 서버)를 배포하십시오.
  3. Terratest의 도우미를 사용하여 HTTP 요청, API 호출, SSH 연결 등을 만들어 해당 환경에서 인프라가 올바르게 작동하는지 확인하십시오.
  4. Terratest의 도우미를 사용하여 테스트가 끝날 때 모든 것을 배포 해제하십시오.

다음은 일부 Terraform 코드에 대한 테스트 예제입니다.

terraformOptions := &terraform.Options {
  // The path to where your Terraform code is located
  TerraformDir: "../examples/terraform-basic-example",
}

// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions)

// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)

// Run `terraform output` to get the value of an output variable
instanceUrl := terraform.Output(t, terraformOptions, "instance_url")

// Verify that we get back a 200 OK with the expected text
// It can take a minute or so for the Instance to boot up, so retry a few times
expected := "Hello, World"
maxRetries := 15
timeBetweenRetries := 5 * time.Second
http_helper.HttpGetWithRetry(t, instanceUrl, 200, expected, maxRetries, timeBetweenRetries)

이는 통합 테스트이며 테스트 대상에 따라 5-50 분 정도 걸릴 수 있습니다. 그것은 (사용하지만 빠른 아니다 도커테스트 단계 , 당신은 속도를 높일 수 있습니다 가지 업), 당신은 테스트가 신뢰성을 할 일을해야하지만, 시간이 충분하다.

Terratest 저장소 에서 다양한 유형의 인프라 코드 및 이에 대한 테스트에 대한 문서 및 예제를 확인하십시오 .


1
또한 Terratest를 사용하여 예제 프로젝트 중 하나를 자세히 테스트하는 블로그 게시물 인 brightfame.co/blog/…도 작성했습니다 . 누구에게나 가치가있을 수 있습니다. 건배, 롭!
Rob Morgan

Terratest의 큰 팬!
jlucktay

7

언급 된 다른 모든 옵션 외에도 InSpec 2.0은 클라우드 공급자 API에 대한 지원을 추가했다고 언급하고 싶습니다. 기본적으로 Terraform으로 IaC를 계속 작성하고 클라우드 리소스에 대한 InSpec을 사용하여 호환성 검사를 작성할 수 있습니다. 또한 InSpec은 필요할 경우 개별 시스템에 대한 테스트 작성을 지원합니다.

다음은 Terraspec과 함께 Inspec을 사용하는 방법에 대한 Christoph Hartmann (Inspec 공동 제작자)의 기사입니다. https://lollyrock.com/articles/inspec-terraform/


5

Aws-Side에는 https://github.com/k1LoW/awspec 이 있습니다. terraform.state를 피드하고 terraform이 올바르게 적용되었는지 테스트 할 수 있어야합니다.

그러나 툴을 낮은 수준에서 테스트하는 것 외에도 전체 인프라를 테스트하는 방법에 대해 생각하는 것이 더 좋습니다.

우리는 여기서이 아이디어에 관해 논의하고 있습니다 :

https://github.com/DomainDrivenArchitecture/dda-cloudspec/blob/development/README.md

불변량을 사전에 테스트하기 위해 사용할 준비가 된 솔루션을 모르겠습니다 ...

우리는 요소 이름 의 혼합 terraform plan -out=plan.dumpgrep부재 이름을 사용하여 몇 가지 실험을 수행했습니다 . github.com/hashicorp/terraform/issues/11883에서 더 접근하기 쉬운 계획 형식에 대한 토론이 있습니다.

그러나 현재 인프라의 중요한 부분에 대해 수동 계획 검토 프로세스를 사용하고 있습니다.


4
목표는 너무 늦게 배치 된 테라 폼 구성의 변경 사항을 테스트하여 늦게 배치했을 때, DB가 제거되지 않아야하는 위치에서 DB가 제거되지 않았지만 이미 대상 환경을 중단 한 것을 보는 데 실패한 것입니다. .. 문제는 최종 결과, 단위 테스트 대 통합 테스트를 테스트하지 않고 테라 폼 코드를 테스트하는 것입니다.
Tensibai

좋은 지적은 ... 불변량 테스트 섹션을 추가했습니다.
jerger

0

GitHub 문제 스레드에서 명백하게 제안 된 Terraform을 테스트하는이 우아하고 기술이 낮은 방법을 보았습니다 . 모든 상황에 적합하지는 않지만 모듈 논리를 확인하는 데 좋습니다.

테스트중인 모듈을 포함하는 루트 모듈을 작성하고 테스트중인 출력을 확인하십시오. 다음은 두 파일을 사용하는 간단한 예입니다.

  • main.tf 테스트를 실행합니다
  • simple_module/outputs.tf 테스트중인 모듈을 나타냅니다

./main.tf

terraform {
  required_version = ">= 0.12"
}

module "simple_module" {
  source = "./simple_module"
}

locals {
  expected = 1
  got      = module.simple_module.module-returns-1
}

# Test Output
output "expect-1" {
  value = upper(local.expected == local.got)
}

output "expect-other" {
  value = "other" == local.got ? upper(true) : "FALSE. Got ${local.got}"
}

./simple_module/outputs.tf

output "module-returns-1" {
  value = 1
}

테스트를 실행

terraform init
terraform apply -auto-approve
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

expect-1 = TRUE
expect-other = FALSE. Got 1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.