Cloud/IaC

Terraform Cloud를 통한 Git Repo 기반 인프라 프로비저닝

Omoknooni 2025. 6. 20. 17:37

앞서 우리는 로컬에서 Terraform 코드를 작성하고, CLI를 통해 적용(Apply)하면서 Terraform을 사용하고 있었다.

인프라를 코드로 관리하는 IaC에 목적에 맞게 사용되긴하지만, 팀 간의 협업 속에서 상태(state)관리와 자동화 파이프라인 등에 있어서 분명 아쉬운 부분이 존재했다.

 

서비스 개발운영에서는 Jenkins나 Github Actions, ArgoCD와 같은 툴들을 통해 통합 빌드/배포 과정을 구현해왔지만, 인프라 개발운영 부문에서는 최적화된 플랫폼은 CSP 별로 존재하는 IaC 서비스외에는 마땅히 존재하는 것이 없었다.

 

이에 등장한 Terraform Cloud를 알아보도록 한다.

 

Terraform Cloud

Hashicorp에서 운영하는 Managed 서비스 플랫폼으로, 개인을 넘어 팀 단위의 Terraform의 사용을 지향하는 목적으로 구성되어있다.

테라폼 프로젝트의 Remote Backend로써 State 관리와 VCS(Github, Bitbucket 등)와의 연동 기능을 지원한다.

핵심 컴포넌트

Terraform Cloud는 크게 3가지 컴포넌트를 통해 state를 관리한다.

Organization

Terraform Cloud에서의 최상위 단위, Workspace/Project를 묶는 단위로 Organization명은 고유해야한다.

Project

Workspace의 그룹 역할, 여러 Application들을 구성하는 폴더 개념으로 볼 수 있다.

Workspace

하나의 인프라 프로젝트 단위, 각 workspace 별로 state와 변수, VCS 연결을 가지고 독립적으로 실행된다.

staging, development, production같이 여러 Application들을 구성한 각각의 환경 개념으로 볼 수 있다. 

 

Workspace에서 뿐만 아니라, Organization과 Project 상에서도 변수를 구성해서 그 안에서 공통적으로 사용할 수 있다.

 

실습

Terraform 코드를 통한 AWS 리소스 생성

이번에는 테스트용으로 AWS 계정 환경 상에 몇가지 리소스를 생성해보도록 한다.

이 프로젝트의 state 저장을 Terraform Cloud로 설정하기 위해 아래와 같이 workspace를 지정하는 terraform 블록을 생성해야한다.

# Terraform Cloud를 backend로 지정
terraform {
  cloud {
    organization = "infra-team"
    workspaces {
      name = "terraform_study"
    }
  }
}

 

그리고 AWS 계정에 대해 리소스 생성을 위한 Credential이 주어져야 한다.

workspace의 환경변수를 통해 Credential을 입력하도록 아래같이 구성해본다.

terraform {
    required_providers {
        aws = {
            source = "hashicorp/aws"
            version = "~> 5.0"
        }
    }
}

provider "aws" {
    region = var.aws_region
    access_key = var.AWS_ACCESS_KEY_ID
    secret_key = var.AWS_SECRET_ACCESS_KEY
}

 

 

Github Repo와 연동

팀에서 이 Repo로 Terraform Cloud를 통해 인프라 작업을 협업하는 상황을 가정해보자.

Terraform Cloud가 이 Repo를 참조할 수 있도록 구성해야한다.

 

Organization과 Project를 생성한 뒤, Workspace를 생성하려면 아래와 같이 3가지 Workflow 옵션이 주어진다.

 

Terraform 적용 작업이 트리거되는 방식을 선택하는 부분이며, 트리거 기반을 VCS/CLI/API 중에서 선택하게된다.

이번에는 코드 Repo와 연동해볼 것이므로 `Version Control Workflow`를 선택한다.

 

다음으로 연결할 VCS를 선택하게된다.

Github/Gitlab/Bitbucket/Azure DevOps를 지원하며, Terraform Cloud가 선택한 VCS와 연결하기 위해 인증하는 Integration 작업을 진행하게 된다.

 

그리고 Repo를 선택하게 되며, 간단한 Terraform 프로젝트 repo를 생성해서 이용하도록 한다.

하단의 'Advanced Options'에서는 이 workspace에 대해 트리거나 경로를 지정해줄 수 있다.

 

 

먼저 `working directory`에서는 Terraform이 실행될 Repo의 경로를 지정해준다.

즉, 이 경로지정은 하나의 Repo에 여러 환경들이 디렉토리별로 구분되어있을때 workspace에 지정해주는 옵션이다.

 

`auto-apply`는 이 workspace가 자동으로 Apply를 실행할 것인지를 설정하는 부분이다. 기본적으로 workspace에 지정한 terraform 프로젝트는 plan 수행 이후 유저의 Approve가 있어야 Apply 작업이 수행되도록 지정되어있다.

  • API,UI&VCS : 이 workspace에 대한 Plan이 성공적이면 자동으로 Apply를 수행하도록
  • run triggers : 다른 workspace에서 이 workspace에 trigger를 설정했을때, 자동으로 Apply를 수행하도록

 

`VCS Triggers`에서는 workspace에 지정한 VCS에 대해 어떻게 작업을 트리거할지 유형을 설정하는 부분이다.

  • Branch-based : Repo의 특정 브랜치에 대해 변경점이 생겼을때 작업을 트리거
  • Tag-based : Repo의 특정 포맷의 태그에 대해 변경점이 생겼을때 작업을 트리거

 

이렇게 VCS repo의 지정을 마치면 workspace가 생성된다.

앞서 Repo에서 terraform 리소스를 만들때, AWS Access Key를 Terraform 변수로 지정을 해주었기에 workspace에서 이 변수 값을 생성해주어야한다.

 

Secret Key와 같은 민감정보들을 변수로써 생성하려면, `Sensitive` 옵션을 지정해서 UI나 API 상에 직접 노출되지 않도록 할 수 있다. Github Repo의 Secret 같이 쓰기만 되고, 수정할때 기존 값을 확인할 수 없는 것을 볼 수 있다.

 

 

 

작업(run) 트리거

이제 본격적으로 인프라 리소스를 생성해보도록 한다.

Terraform Cloud의 workspace가 인프라 코드가 저장된 Github Repo를 바라보도록 되어있고, 작업을 트리거하면 Planning과 Apply가 Terraform Cloud 환경에서 이뤄지게 된다.

이를 통해 인프라 state가 Terrform cloud의 workspace를 통해 관리되는 것이다.

provider "aws" {
  region = "us-east-1"
  access_key = var.AWS_ACCESS_KEY
  secret_key = var.AWS_SECRET_ACCESS_KEY
}

resource "aws_instance" "tfcloud_test" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"

  tags = {
    Name = "HelloWorld"
  }
}

....

 

 

앞서 AWS 서비스에 대해 작업하기 위한 Access Key를 Terraform cloud에 Variables로 넣어 주었기에, terraform 코드에서도 variables를 통해 동일한 이름으로 access key들을 받아오도록 지정한다.

variable "AWS_ACCESS_KEY" {
  type = string
}

variable "AWS_SECRET_ACCESS_KEY" {
  type = string
}

 

 

이제 이 변경내역들을 Repo에 push하면 Terraform Cloud의 workspace에서 작업 trigger가 발생된다.

 

Trigger에 따라서 Planning이 이뤄지고, planning을 성공적으로 마치면 Apply하기 위해 추가적인 Approve Action을 주어야한다.

(앞서 Auto-apply를 적용하지 않았기에)

Apply까지 완료되면 인프라 state를 원격 클라우드 환경에 두는 IaC 환경을 구축하게 된다.

 

Repo 기반 인프라 운영

이제 이 인프라는 오직 Repo의 내용을 기반으로 구성된다. 이 상황에서 기존 인프라의 내용을 수정하는 과정을 봐보도록 하자

예를 들어, 이 인스턴스에 새로운 보안그룹을 생성해서 연결해본다.

resource "aws_security_group" "web-sg" {
  name = "web-sg"
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

 

 

변경 내역을 위와 마찬가지로 repo에 커밋&push 하면 Terraform cloud의 workspace에서 작업이 Trigger되며, plan과 apply를 통해 적용되는 것을 볼 수 있다. 

 

이렇게 Github Repo내용을 바탕으로 하는 Terraform IaC 기반의 인프라 운영의 기본 구축을 알아보았다.

 

하나 짚고 넘어갈 점은, AWS 리소스에 접근하기 위해 액세스 키를 워크스페이스 변수로 직접 등록했다는 사실이다. 직접 사용하는데에는 문제가 없지만, 이러한 장기 자격증명은 관리 부담이 크기 때문에, 가능하다면 임시 자격증명 방식을 활용하는 것이 더욱 바람직할 것이다.

IAM Role같이 임시 자격증명을 통해 접근하도록 구성할 수는 없을까?

이를 해결하기 위한 방법을 바로 다음에 알아보도록 한다.