Home | 문태준 | 시스템어드민 메일링 | Sys Admin 세미나
Skip to end of metadata
Go to start of metadata

설치, 설정

AWS 설정

사용하는 AWS key는 named profiles 를 이용하여 terraform 코드에 설정을 하도록 한다. 사용자가 실수로 terraform 코드를 잘못 실행하는 것을 방지하기 위한 목적이다.


terraform module 설정

module 을 사용을 하면 terraform init 명령을 실행한 경우 설정을 한 provider 프로그램을 다운로드 받는다.

그런데 각 module 마다 provider를 따로 다운로드 받기 때문에 시간이 많이 걸린다.

홈디렉토리의 .terraformrc 파일에 plugin cache 설정을 해서 사용을 한다.  이 디렉토리는 terraform이 자동생성하지 않기 때문에 수동으로 생성을 해준다.

https://www.terraform.io/docs/configuration/providers.html

terraform 사용하기

terraform을 사용할 때 처음부터 코드를 새로 짜는 것보다는 terraform module 을 참고한다.

외부 모듈을 쓰는 것이 확실하게 좋은 경우가 아니라면 가급적 직접 코드를 짜는 것이 좋을 수 있다.  일부 리소스는 직접 만들고 일부 리소스는 외부 모듈을 이용하는 경우 혼란스러울 수 있다.

  1. terraform module registry  https://registry.terraform.io/browse?provider=aws : Verified 는 사용을 해도 좋지만 그 외의 것은 코드 수준이 다양하므로 코드를 보고 판단해야 한다.
  2. best practicces terraform : https://github.com/hashicorp/best-practices/tree/master/terraform : 현재 deprecated 이고 terraform module registry를 참고하라고 하지만 terrafrom 전체적인 코드를 보기에는 도움이 된다.
  3. terraform examples https://github.com/terraform-providers/terraform-provider-aws/tree/master/examples
  4. github 등에서 검색

엔터프라이즈 환경에서 terraform 사용하기

https://www.terraform.io/docs/enterprise/guides/recommended-practices/index.html (한글자료 https://blog.outsider.ne.kr/1333)

https://learn.hashicorp.com/terraform/development/running-terraform-in-automation

https://learn.hashicorp.com/terraform/operations/maintaining-multiple-environments

terraform workspace 활용 https://www.terraform.io/docs/state/workspaces.html

디렉토리 구조

....

환경구분 : prod , staging , ......

remote state 설정

https://www.terraform.io/docs/state/remote.html

terraform 에서는 기본으로는 terraform.tfstate 파일을 로컬에 저장한다. 여러 명이 함께 협업을 할 경우에는 불편한 부분이 있으며 remote state를 설정해서 state 데이터를 원격의 저장소에 놓고 사용을 할 수가 있다. remote state 를 지원하는 backend type 은 consul, s3 등이 있다. 

consul의 경우에는 remote state + locking을 지원하고 s3를 이용하는 경우에는 locking도 사용하려면 DynamoDB 도 함께 써야 한다. s3에서 버저닝 기능을 이용하면 예전의 state 파일로 복구 가능한 장점이 있다.

코드 가이드라인

README 파일 만들기 : 코드를 보고 판단 가능한 경우는 생략해도 되지만 설명이 필요한 경우는 README 파일 필수

main.tf : variables, data, module 호출. output.  작업 성격에 따라서 main.tf 의 내용을 특정 AWS resource에 따라 여러 개의 파일로 구분할 수 있다.

provider.tf : region, profile 지정

terraform.tfvars : 변수

backend.tf : remote state 설정

 

AWS key는 provide 의 profile에 지정을 한다.

 

$ cat provider.tf
provider "aws" {
  region  = "${var.region}"
  profile = "${var.profile}"
}

 

 

다른 AWS  리소스 정보가 필요할 경우 변수를 하드코딩 하는 것보다는 data source 를 이용하여 tag 등에서 검색을 해서 가져오는 것이 좋다. 그러면 prod, staging 에 상관없이 동일한 코드를 짤 수 있다.

 

data "aws_vpc" "selected" {
  filter {
    name   = "tag:Name"
    values = ["${var.vpc_name}"]
  }
}
 
...
  vpc_id      = "${data.aws_vpc.selected.id}"
...

 

 

각 리소스를 조건에 따라 생성, 삭제할 수 있게 count 변수를 잘 활용하면 편리하다. 예를 들어 staging 에는 만들 필요가 없고 prod 에만 특정 리소스가 필요할 경우  staging 에서는 count 를 0으로 설정을 하면 된다. 모듈에 있는 코드들은 보통 이런 식으로 구현을 해 놓았다.

 

https://github.com/jonbrouse/terraform-style-guide 등 참고.

Strings are in double-quotes.

Spacing : Use 2 spaces 

Resource Block Alignment

Terraform resource name :  underscore(_) 사용

 

resource "aws_security_group" "security_group" {
...

 

 

resource 의  name 에는  hyphen(-)  사용. 

 

resource "aws_security_group" "security_group" {
 name = "${var.resource_name}-security-group"
...

 

 

https://github.com/hashicorp/best-practices/tree/master/terraform/providers/aws/us_east_1_prod

 

참고로 terraform 의 terraform fmt 명령을 이용하면 자동으로 코드 스타일을 맞출 수 있다. 이런 부분을 commit hook에 넣어서 사용할 수도 있겠다.

 

$ terraform fmt test.tf

 

lifecycle

create_before_destroy :   새로운 리소스를 먼저 생성하고 기존의 리소스 삭제.

 

ignore_changes 

terraform 에서 리소스의 설정 내용 중 변경사항이 있으면 해당 리소스를 삭제하고 다시 생성한다. 특정 속성의 변경사항이 있어도 해당 리소스를 재생성하는 것을 막으려면 lifecycle 에서 ignore_changes 를 이용하면 된다.

https://www.terraform.io/docs/configuration/resources.html

 

$ cat sample.tf
resource "aws_instance" "service" {
  instance_type          = "${var.instance_type}"
  ami                    = "${lookup(var.amis, var.os)}"
  key_name               = "${var.aws_key_pair}"
  subnet_id              = "${var.subnets}"
  vpc_security_group_ids = ["${var.security_group_ids}"]
  iam_instance_profile   = "${data.aws_iam_instance_profile.ec2_common_iam_instance_profile.name}"
 
  user_data = "${data.template_cloudinit_config.config.rendered}"
 
  tags {
    Name        = "${var.name}"
    Owner       = "${var.owner}"
    Environment = "${var.environment}"
  }
 
  lifecycle {
    ignore_changes = ["ami","user_data"]
  }
 
}

 

terraform module  - AWS

 

terraform module  - AWS

Verified 는 사용을 해도 좋지만 그 외의 것은 코드 수준이 다양하므로 코드를 보고 판단해야 한다.

https://registry.terraform.io/browse?provider=aws&verified=true

terraform module registry를 이용하지 않는다고 하더라도 재사용 가능한 코드가 있는 경우에는 module을 이용하는 것이 좋다. 

https://www.terraform.io/docs/modules/create.html

어떤 경우 모듈을 짜는게 좋은지는 https://www.terraform.io/docs/enterprise/guides/recommended-practices/part3.2.html 문서 참고.

아키텍쳐 패턴일 경우

VPC, RDS cluster 등 여러개의 설정이 필요한 서비스

EC2+ELB, autoscalinig group 등과 같이 여러 리소스 타입에 대해서 별도 설정이 필요한 경우

Terraform 디버깅

https://www.terraform.io/docs/internals/debugging.html

TF_LOG 환경변수로 설정할 수 있다. log level : TRACEDEBUGINFOWARN or ERROR

 

$ export TF_LOG=DEBUG ; terraform plan 
Labels
  • No labels