끄적끄적

[Terraform] terraform cloud 사용하기 본문

개발/인프라

[Terraform] terraform cloud 사용하기

코리이 2022. 11. 6. 19:12

필자는 회사에서 테라폼을 이용해서 AWS 관리를 하는데 backend 는 여러가지 이유 때문에 S3 + dynamodb 를 활용한다.

그런데 테라폼 클라우드를 활용하면 백앤드 관리를 더 편하게 할 수 있다는 이야기가 있어 이번에 사이드 프로젝트를 하면서 한번 써보고자 했다.

시작하기

테라폼 클라우드를 사용하는 방법은 오히려 S3 를 활용하는 것보다 쉽다.

우선 테라폼 클라우드 홈페이지로 가서 계정을 생성하자.

 

그러면 organization 을 만들라고 할 것이다. 사용할 프로젝트의 organization 을 만들어주자

 

이제 필요한 workspace 를 만들라고 한다.

이 workspace 가 테라폼에서 작성할 각각의 인프라가 될 것이다.

예시로 vpc 하나를 만드는 테라폼 workspace 를 만들어보자.

만약 git 을 연동하여 CI/CD 를 활용하고 싶다면 version control 도 연결하면 된다.

하지만 필자의 경우 일단 혼자서 인프라를 관리하므로 cli 기반으로만 작동하도록 설정했다.

cli 기반을 선택한 후 그 후 workspace 이름을 만들어 생성한다.

 

 

 

이렇게 하면 바로 workspace 가 생성된다.

하지만 현재 실행 모드가 remote 인데 이는 테라폼 실행을 내 컴퓨터가 아닌 테라폼 클라우드 내에서 실행한다는 뜻이다.

즉, 이 설정에서는 aws key 등을 넣어줘야 실행이 된다는 것을 알 수 있다.

local 방식은 state 만 클라우드에 보관하고 실행은 각자의 컴퓨터에서 실행한다는 뜻으로 S3 를 일반적으로 사용한다면 같은 방식으로 동작한다고 생각하면 될 것 같다.

그래서 테스트를 위해 우선 local 에서 실행하기 위해 worksapce/{vpc 워크스페이스}/settings/general 페이지로 이동해서 remote 방식을 local 방식으로 변경하자.

 

이제 테스트를 위해 간단한 테라폼 코드를 작성하자. 각자의 컴퓨터에 aws config 설정은 알아서 하자.

실습을 위한 디렉토리는 다음과 같다.

 

우선 vpc 워크스페이스의 remote 설정을 terraform cloud 로 설정해 주어야 한다.

backend.tf 파일에 아래를 작성해주자.

# backend.tf
terraform {
  backend "remote" {
    hostname = "app.terraform.io"
    organization = "my-sample-pawmi"

    workspaces {
      name = "pawmi-vpc"
    }
  }
}

그리고 이제 vpc 를 만드는 테라폼 코드를 작성해준다.

변수로는 aws profile 과 region 을 받아서 처리할 것이다.

# main.tf
terraform {
  required_version = ">= 1.3.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.38"
    }
  }
}

provider "aws" {
  region  = var.aws_region
  profile = var.aws_profile == null ? null : var.aws_profile
}

resource "aws_vpc" "default" {
  cidr_block = "10.10.0.0/16"
}

variable "aws_region" {
  description = "The region of infra"
  type        = string
}

variable "aws_profile" {
  description = "The profile of infra"
  type        = string
  default     = null
}

이제 테라폼 클라우드를 백앤드로 실행시켜보자

init → plan → apply 를 순서대로 실행시켜주자.

# terraform init
$ terraform init

# terraform plan
$ terraform plan -out=./tfplan -var="aws_region=ap-northeast-2"

# terraform apply
$ terraform apply "./tfplan"

그러면 cli 에서 실행되는 화면을 볼 수 있을 것이다.

완료가 되었다면 다시 terraform cloud 워크스페이스에 잘 생성되었는지 확인해보자.

아래처럼 vpc 가 생성되었다면 성공적으로 완료한 것이다.

 

remote 로 실행하기

혼자서 개발할때는 local 에서 해도 좋지만 아마도 대부분이 remote 에서 실행해야 충돌도 안나고 내 컴퓨터에 오류가 생겨도 해결할 수 있을 것이다.

그래서 이번에는 remote 방식으로 변경하기 위해 다시 worksapce/{vpc 워크스페이스}/settings/general 페이지로 이동해서 local 방식을 remote 방식으로 변경하자. (Remote state sharing) 은 다음 챕터에서 설명한다.

 

이제 remote 방식이기 때문에 AWS credential 설정을 해주지 않으면 인증 에러가 날 것이다.

그래서 이를 적용하기 위해  organization/Settings/Variable sets 으로 이동해주자.

생성하기를 누르고 AWS 관련 시크릿 정보를 넣는다. 

이때 dev, prod 나눠서 credential 을 적용하기 위해 전체 workspace 에 적용하지 말고 특정 workspace 에서 선택하도록 설정한다.

 

 

Credential 값은 테라폼 변수가 아니라 환경변수(env) 이고, 보안 정보이니 sensitive 를 클릭한다. 

AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY 두 정보를 모두 입력한다.

 

 

이제 remote 로 실행하면 되는데 문제점 중 하나가 variable 을 cli 에서  입력할 수 없다는 점이다. 또한 tfvars 파일도 지정할 수 없다. 공식문서에 보면 variable 을 코드에서 넣고 싶다면 *.auto.tfvars 만 가능하다고 한다.

만약 auto.tfvars 파일 말고 직접 테라폼 환경에 넣어줄 수도 있다.

어차피 AWS Credential 설정을 한번 더 해야하니 한꺼번에 설명하겠다.

worksapce/{vpc 워크스페이스}/variables 로 페이지를 이동한 후 필요한 변수를 넣어주면 된다.

현재 코드에서는 aws_region 을 넣어줘야 하므로 아래처럼 workspace 변수로 region 을 입력해준다.

 

 

그리고 AWS Credential 을 넣어주기 위해 앞에서 지정했던 Variable Sets 를 가져오자

Apply variable set 을 클릭한 후 credential 을 선택해주면 성공적으로 적용이 될 것이다. 

 

 

이제 모든 환경설정이 끝났다. remote 환경에서 실행하는 방법도 cli 명령어 자체는 다르지 않다.

앞에서 init 을 했으므로 plan 을 해서 remote 로 실행되는지 확인해보자. 하지만 변경사항이 있어야 적용이 되므로 vpc 에 subnet 을 하나 생성하자

resource "aws_subnet" "default" {
  vpc_id            = aws_vpc.default.id
  cidr_block        = "10.10.0.0/24"
  availability_zone = "ap-northeast-2a"

  map_public_ip_on_launch = false
}

output "default_subnet_id" {
  value = aws_subnet.default.id
}

그후 plan 을 통해 remote 로 실행되는지 확인하자.

아래처럼 url 을 통해 실행되는 것을 확인할 수 있다.

$ terraform plan

 

실제로 웹페이지에 접속하면 실행 결과를 확인할 수 있다.

 

 

하지만 local 에서 실행했던 것과는 다르게 plan -out 옵션을 따로 사용하지 못한다.

그래서 단순 apply 를 통해 실행시켜야 한다. 만약 auto-apply 기능을 꺼놨다면 필자처럼 cli 에서 yes 버튼을 누를 수 있도록 나올 것이다. ui 에서는 pending 이 되어 있는 것도 확인할 수 있다.

그럼 apply 를 통해 subnet 을 생성하자.

$ terraform apply

 

데라폼 클라우드 ui 를 확인하면 성공적으로 적용된 것을 확인할 수 있다.

 

remote state 로 공유하기

이제 vpc 를 만들어 줬으니 service 생성을 위해 service 워크스페이스를 만들어주자.

ec2 를 만들건데 subnet 을 변수로 넣어줘야 하므로 vpc 의 subnet state 를 필요로 할 것이다.

우선 워크스페이스 생성의 경우 동일한 방식으로 작성하자

필자의 경우 pawmi-service 의 이름으로 생성했다. remote 로 만들고, 환경변수를 설정해주자.

그리고 서비스 관련 terraform 코드를 작성하자

# backend.tf
terraform {
  backend "remote" {
    hostname = "app.terraform.io"
    organization = "my-sample-pawmi"

    workspaces {
      name = "pawmi-service"
    }
  }
}

maint.tf 에서는 state 를 가져오기 위해 remote state 를 설정해줬다.

서비스 테라폼 코드는 아래와 같다.

terraform {
  required_version = ">= 1.3.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.38"
    }
  }
}

data "terraform_remote_state" "vpc" {
  backend = "remote"

  config = {
    hostname = "app.terraform.io"
    organization = "my-sample-pawmi"

    workspaces = {
      name = "pawmi-vpc"
    }
  }
}

provider "aws" {
  region  = var.aws_region
  profile = var.aws_profile == null ? null : var.aws_profile
}

data "aws_ami" "amazon_linux_2" {
  most_recent = true

  filter {
    name   = "owner-alias"
    values = ["amazon"]
  }
  
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm*"]
  }

  owners = ["amazon"]
}

resource "aws_instance" "default" {
  ami = data.aws_ami.amazon_linux_2.id
  instance_type     = "t2.micro"
  availability_zone = "ap-northeast-2a"
  associate_public_ip_address = true
  subnet_id                   = data.terraform_remote_state.vpc.outputs.default_subnet_id
}

variable "aws_region" {
  description = "The region of infra"
  type        = string
}

variable "aws_profile" {
  description = "The profile of infra"
  type        = string
  default     = null
}

하지만 remote state 를 사용하기 위해서는 하나의 작업이 더 필요하다.

vpc 의 state 를 serivce 가 사용할 수 있도록 설정해주는 작업이다.

worksapce/{vpc 워크스페이스}/settings/general  페이지로 이동해서 Remote state sharing 부분을 service 가 이용할 수 있도록 수정해주자.

 

그러면 이제 service 워크스페이스에서도 vpc state 를 사용할 수 있게 된다.

확인하기 위해 테라폼을 실행시켜 보자

$ terraform init

$ terraform apply

성공적으로 완료 되었다면 테라폼 클라우드 ui 에도 나올 테고

실제 AWS 에도 생성되어 있는 것을 확인할 수 있을 것이다.

 

테라폼 클라우드 ui
AWS console

마무리

모든 실습이 끝났다면 destroy 를 통해 모든 인프라를 제거하는 것을 잊지 말자

# service 제거
$ cd ${root_infra}/service
$ terraform destroy

# vpc 제거
$ cd ${root_infra}/vpc
$ terraform destroy

결론

평상시에는 S3 + dynamodb 를 이용해서 state 관리를 하는데 테라폼 클라우드를 쓰니 ui 로 확인할 수 있는 점이 흥미로웠다.

또한 remote 로 실행시키면 실행하는 과정도 lock 이 자동으로 걸려 편하게 사용할 수 있었다.

만약 보안 컨플라이언스에 문제가 없다면 오히려 terraform cloud 로 state 들을 관리하는게 편할 것 같다.

딱 하나 단점이 있다면.. 느리다는 점 하나인 듯 싶다.

'개발 > 인프라' 카테고리의 다른 글

[Docker] PID1 과 SIGTERM 문제 (feat dumb-init)  (0) 2023.08.25