본문 바로가기
Terraform

Terraform 키관리 및 실습

by Nirah 2023. 2. 13.

Terraform 

 

CDN 종류. (코드정의네트워크)

 

테라폼Terraform은 하시코프Hashicorp에서 오픈소스로 개발중인 클라우드 인프라스트럭처 자동화를 지향하는 코드다.

= 인프라스트럭처Infrastructure as Code

테라폼에서는 하시코프 설정 언어HCL, Hashicorp Configuration Language을 사용해 클라우드 리소스를 선언한다.

아마존 웹 서비스Amazon Web Service가 자체적으로 만든 AWS 클라우드 포메이션AWS CloudFormation의 경우 AWS만 지원하는 것과 달리 테라폼의 경우 아마존 웹 서비스Amazon Web Service, 구글 클라우드 플랫폼Google Cloud Platform, 마이크로소프트 애저Microsoft Azure와 같은 주요 클라우드 서비스를 비롯한 다양한 클라우드 서비스들을 프로바이더 방식으로 제공하고 있다.

이를 통해 테라폼만으로 멀티 클라우드의 리소스들을 선언하고 코드로 관리하는 것도 가능하다.

 

GUI로 aws 설정하는건 편하고 쉽긴 한데, 대량의 컴퓨터에 설정하려면 스크립트 형식이여야 좋다.

그래서 aws cli와 테라폼 쓴다.

 

공식 튜토리얼

https://developer.hashicorp.com/terraform/language/syntax/configuration

 

Syntax - Configuration Language | Terraform | HashiCorp Developer

Key constructs of the native Terraform language syntax, including identifiers, arguments, blocks, and comments.

developer.hashicorp.com

 

lac의 장점

우리는 항상 무언가를 직접 손으로 하는 것이 아닌 코드로써 작성하고 실행할 때 공통적으로 얻는 장점이 있다.

  • 자동화가 가능하다.
  • 한번 작성할 때는 시간이 걸리겠지만, 그 후에는 몇번이고 빠르게 구축이 가능하다.
  • 사람이 하지 않기 때문에 실수를 하지 않는다. 인프라는 특히나 실수를 하면 안되는 매우 민감한 분야다.

 

 

Terraform의 장점

다른 IaC도구 특히, Ansible과 같은 설정 관리 도구에 비해서 Terraform이 갖는 장점은 다음과 같다.

  1. 선언형 언어이다.
  2. 마스터/에이전트가 아니다.

Ansible의 경우는 다음 코드로 그 구성을 할 수 있다.

- ec2:
    count: 10
    image: ami-40d28157
    instance_type: t2.micro

Terraform은 다음과 같이 구성할 수 있다.

resource "aws_instance" "example" {
    count = 10
    ami = "ami-40d28157"
    instance_type = "t2.micro"
}

근데 5대를 추가해야 한다고 해보자 Ansible은 다음과 같이 코드를 업데이트 해야 한다.

- ec2:
    count: 5              # 이미 10대가 있으니까 나머지 5대
    image: ami-40d28157
    instance_type: t2.micro

Terraform은 다음과 같이 코드를 업데이트한다.

resource "aws_instance" "example" {
    count = 15
    ami = "ami-40d28157"
    instance_type = "t2.micro"
}

여기서 중요한 점은 Terraform은 구성될 인프라스트럭처의 "최종 결과"를 선언한다는 것이다. Ansible의 경우에는 변경 이력을 모두 알고 있어야 원하는 인프라스트럭처 구성을 할 수 있다. 만약 자신은 10대라고 생각하고 5대를 추가했는데 이미 누군가 2대를 추가하면 어떨 것 같은가? 이러한 변경 이력을 모르면 결국 리소스 낭비가 이루어진다는 것이다. 이런 점에서 Terraform은 매우 큰 장점을 가지고 있다.

 

또한 마스터/에이전트 구조가 아니다. 따라서 서버를 나눌 필요도 없으며 모든 서버에 설치할 필요도 없다. 일반적으로는 (Terraform을 설치해서 인프라스트럭처를 관리하는 용도의 서버를 1대 두는 듯 하다.) 구성 관리 도구는 Ansible을 제외한 나머지 기술들은 모두 마스터 서버와 각 서버들에 에이전트를 설치해야 한다. 이는 운영하는데 복잡도를 높이는 한 요인이 된다. Terraform은 운영 면에서도 구성 관리 도구에 비해 쉽다는 장점을 갖게 된다.

 

destroy 기능을 통해 자신이 구성한 리소스를 한번에 제거 가능한 것도 큰 편의성을 지닌다.

자신이 코드로 작성한 인프라만 삭제가 되기 때문에 실수로 옆에서 돌고 있는 Production Server를 삭제할 위험도 줄어든다.

 

 

 

 

용어

Provider: aws, azure, gcp

Resource : 인프라 자원 (AWS_xxx) : 지정됨 리소스는 AWS로 예를 들자면 EC2, RDS 등과 같이 실제로 구축하게 될 자원(서비스)을 말한다.

State : 결과물에 상태 정보 저장된 파일

Variable : string, map (aws configure에 키값이 저장돼있으면 바이패스 해주기만 하면됨)

 

 

 

 

적용 순서

 

Terraform은 다음과 같은 적용 단계를 거친다.

따로 cli 창을 켜서 동시에 확인하면 좋다 (모바x텀같은)

 

  1. init을 실행하면 provider에서 라이브러리를 다운받는다. (.tf파일) (provider에 대한 정의파일을 만들어줘야함)
  2. Plan: 잘 작동하는지 --dry-run 같은 테스트
  3. Apply: 적용단계. plan까지 잘 됐는데 여기서 간혹 오류가 날 수도 있긴 하다. terraform apply -auto-aprove

state list: 결과물 상태 정보

destroy : 리소스 모두 삭제 terraform destroy -auto-approve

 

 

 

 

환경변수 설정 툴

비쥬얼박스에서 아래 두개를 설치한다.

 

직전 글에 설치했던 것에 이어서 유저 nini

액세스키

AKIA2UFTESDJ34NU6IXE

비밀 엑세스

ucT1GOXjRuNEpbL+IRDplvvMTlMAVQcM1EbXxbtQ

 

유저 bbb

엑세스키

AKIA2UFTESDJQXKBWFPL

비밀 엑세스키

oL1YlkP8Pc0Ijg2MfgnkQAayR1vAhVRFVJ7oKkbf

 

 

 

테라폼은 기본적으로 *.tf 확장자를 사용한다.

아래와같이 .tf파일을 만들면 환경 변수 파일 만들기를 시작할 수 있다.

 

따로 폴더를 만들어야되지만 귀찮아서 .aws폴더에 config 파일들과 같이두었다.

통째로 한 파일에 코딩하기 보단 variable과 output 등 파일들을 따로 나누어 만들어서 사용하는게 좋다

vars.tf  outputs.tf 파일을 같은 폴더 내에 만들어서 각각의 구문들만 이동시켜서 사용하자

참고로 꼭 이 파일 이름들을 써야 하는건 아니다

terraform 명령을 실행 == 해당 폴더 내의 모든 tf 파일을 실행

이므로 아무렇게나 .tf 파일을 만들어서 사용하면 된다

 

 

 

 

IAM 비밀키 만들기

 

테라폼에서 AWS의 리소스를 프로비저닝 하기 위해서는 작업하고자 하는 내용의 권한을 가진 계정의

ACCESS KEY와 SECRET KEY가 필요하다

루트 계정으로 진행하면 편하지만 보안상 필요최소한의 권한만 있는 IAM User를 만든 후 진행해보겠다

aws에서 관리자 유저에 키를 생성해준다.

 

 

계정

액세스키

AKIA2UFTESDJ34NU6IXE

비밀 엑세스

ucT1GOXjRuNEpbL+IRDplvvMTlMAVQcM1EbXxbtQ

 

 

테라폼에서 AWS의 리소스를 프로비저닝 하기 위해서는 해당 계정의 ACCESS KEY와 SECRET KEY가 필요하다고 했다.

이때 단순히 환경 변수 파일을 작성할 때 내용물 안에 키를 저장해 두는 방식은

키가 파일안에 다 노출돼있어서 보안상 좋지 않다.

그래서 setx나 set으로 미리 엑세스키, 시크릿키를 configure 파일에 저장해놓고 사용하는 방법을 먼저 소개하겠다.

 

configure파일에 키 저장

 

1. 첫 번째로 이렇게 직접 vi편집기마냥  config,credential 파일에 직접 설정하는 방법이 있고,

aws configure

us-west-2

yaml

 

 

2. 두 번째로 set, setx 명령어로 설정하는 방법이 있다.

 

setx vpc id

set | findstr -i vpcid

set AWS_ACCESS_KEY_ID=[본인 계정 액세스 키]

set AWS_SECRET_ACCESS_KEY=[본인 계정 시크릿 키]

 

예를 들어 이런식으로 configure 안의 변수를 바꿀 수 있다.

 

set 명령은 일반 변수 등록이라 현재 터미널에서만 유용하다 (다른 cmd 창을 키면 초기화 되어있음)

영구 등록이 필요하면 setx 명령을 사용하면 되고, linux의 경우엔 export를 사용하면 된다

 

※ 변수를 바꾸면 반드시 cmd창을 재시작 해야 적용되므로 이건 당황하지 말고 꼭 기억하자.

 

 

 

 

환경 변수 설정 확인

cd C:\\terraform

dir

type config

 

type credentials

 

 

set 을 치면 환경변수를 볼수 있다.

 

 

아래와같이 유저 아래 .aws 라는 폴더와 그안에 파일들이 생겨있다.

C:\Users\sesac\.aws

  • configure 명령어로 저장한 내용은 ~/.aws/config 와 ~/.aws/credentials로 나눠서 저장다.
  • credentials에는 인증과 관련된 값들이 저장되고, 그 외의 설정은 config 파일에 저장된다.
  • cat ~/.aws/config #[default] #region = ~
  • # AWS에 있는 모든 s3 버킷 나열 aws s3 ls

configure 설정을 초기화하려면 해당 파일을 삭제하면 된다.

 

 

 

 

테스트1 - vpc생성

아래 사전에서 필요한 AWS cli 명령어를 찾아서 쓰면 편하다.

aws 명령어 사전

https://docs.aws.amazon.com/cli/latest/reference/ec2/

 

ec2 — AWS CLI 1.27.69 Command Reference

Description Amazon Elastic Compute Cloud (Amazon EC2) provides secure and resizable computing capacity in the Amazon Web Services Cloud. Using Amazon EC2 eliminates the need to invest in hardware up front, so you can develop and deploy applications faster.

docs.aws.amazon.com

 

일단 configure은 디폴트이고 confidential은 퍼블릭키, 시크릿키만 입력하고 나머지 디폴트인 상태이다.

vpc를 하나 생성해보자.

aws ec2 create-vpc --cidr-block 10.10.0.0/16

확인할 때 꼭 gui에서 설정했던 리전에 들어가 확인해보자.

디폴트 vpc와 함께 만들었던 vpc가 존재한다.

 

aws cli 명령어로 서브넷들도 만들어본다.

 

aws ec2 create-subnet ^
    --vpc-id %vpcid% ^
    --cidr-block 10.10.1.0/24 ^
    --tag-specifications ResourceType=subnet,Tags=[{Key=Name,Value=alice-public-subnet-1}]

 

aws ec2 create-subnet ^
    --vpc-id %vpcid% ^
    --cidr-block 10.10.2.0/24 ^
    --availability-zone us-west-2a
    --tag-specifications ResourceType=subnet,Tags=[{Key=Name,Value=alice-private-subnet-2}]

 

aws ec2 create-internet-gateway ^
    --tag-specifications ResourceType=internet-gateway,Tags=[{Key=Name,Value=Alice-igw}]

 

 

 

 

 

테스트2 - EC2 생성

 

일단 기본 VPC가 배포되어 있어야 한다 (없으면 작업 > 기본 VPC 생성으로 만든다)

기본 VPC로 진행하면 VPC id나 서브넷 id 등을 지정할 필요가 없다

 

provider.tf

테라폼은 기본적으로 자신이 사용하고자 하는 어떤 특정 리소스를 사용하려고 하면 먼저 해당 리소스를 소유하고 있는 provider라는 것을 선언해주어야 한다. 필자는 EC2를 만들려고 했기 때문에 "aws" provider를 선언해준다.

PROVIDER는 AWS, Azure 등 공급자의 이름이다

따라서 위 구문으로 인해 테라폼은 아마존 웹 서비스의 서울 리전에서 인프라를 배포해야 한다는걸 인지하게 된다.

 

프로바이더는 자기가 멋대로 만들어도 되는 것이 아닌 테라폼이 지원하는 것만 가능한데 약 2-3000개의 프로바이더를 지원한다고 한다. 자세한건 아래의 링크 참조.

 

 

instance.tf

 

"aws_instance"는 해당 리소스의 타입을 뜻하며 EC2를 뜻하는 예약어이다.

"wecserverEC222"는 필자가 해당 EC2에 지어준 별명이다. 이 별명은 테라폼에서만 유효하며, 실제 EC2에 이름이 부여된다거나 하는 것과는 관계없다. 나중에 instance.wecserverEC222 와 같은 형태로 해당 인스턴스를 참조할 수 있다.

 

그 외에는 해당 리소스가 생성되는 필요한 혹은 커스텀할 수 있는 옵션들을 채워넣어주면 된다.

EC2에 필요한 옵션으로써 AMI 버전과 인스턴스 사양, 그리고 필수는 아니지만 간단하게 태그를 붙일 수 있다.

 

 

AMI는 us-west-2 리전의 Amazon Linux 2 이미지의 AMI를 적어넣는다

참고로 해당 ami값은 주기적으로 변경되는 것 같기에 스크립트가 다음날엔 작동하지 않을 수 있다.

나머지 파일들은 설정 안들어있다.

 

 

init : 테라폼을 수행하기 위한 공급자의 최신 플러그인들을 자동 설정 - provider 구문이 설정된 후에 실행할 수 있다

가장 먼저 환경을 초기화해주는 작업이다.

이를 통해 terraform에 필요한 프로바이더 모듈 및 서드파티 라이브러리 등을 로컬에 설치한다. 이는 프로젝트당 초기에 딱 한번만 실행시키면 되지만, 프로바이더 혹은 버전 세팅이 바뀔 경우, 다시 실행시켜주어야 한다.

 

 

그 후에는 해도 되고, 안해도 되는 것들이 있는데 코드 린팅 수정코드 유효성 검증이다.

$ terraform fmt // 코드 이쁘게 정리함
$ terraform validate // 코드 유효성 검증

 

plan : 테라폼이 실행했을 시, 실제로 생성되거나 변경되는 내역을 보여준다

이것의 결과를 보면, 구체적으로 자신의 인프라에 어떤 변화가 일어날 예정인지를 확인할 수 있어서 치명적인 오류를 예방할 수 있다.

 

 

마지막으로 apply 명령으로 테라폼을 실제로 실행시키게 되는데, 변경 내역을 확인한다고 하기 위해 중간에 yes를 한번 쳐주고 진행하면 끝난다

테라폼은 멱등성(Idempotency)이라는 중요한 개념이 있기 때문에, 같은 코드들을 조금씩 변경하면서 실행했을 때 매번 새롭게 생성되는것이 아니라 변경된 부분만 반영되어 프로비저닝된다

잘 만들어졌다

 

 

 

 

 

===========================================================================================

 

 

직접 생성한 키 페어 사용하는 방법

 

직접 자체적으로 ssh rsa키를 생성해서 접근권한을 부여하는 방법도 있다.

 

EC2에 attach할 SSH 키 페어를 생성하기 위해 로컬에 간단하게 SSH 키를 생성해주자. 

Terraform의 file import 기능을 사용하는 원리다.

cmd에서 키페어를 생성한다.

 

ssh-keygen -t rsa -f "C:\Users\sesac\.aws\.bbb"

.aws 파일 아래 bbb폴더를 만들고 그안에 생성한 키페어를 넣어둔다.

 

비쥬얼 박스에서 다음과 같이 작성해준다.

 

 

provider.tf

provider "aws" {
    region = var.AWS_REGION
}

 

 

vars.tf

상대경로로 지정했기 때문에 프로비저닝 할땐 cd로 지정 폴더로 이동한 뒤에 해야한다. (C:\Users\sesac\.aws)

variable "AWS_REGION" {
    default = "us-west-2"
}

variable "PATH_TO_PUBLIC_KEY" {
    default = "./bbb/.bbb.pub"
}

variable "PATH_TO_PRIVATE_KEY" {
    default = "./bbb/.bbb"
}

 

 

instance.tf

ami값은 직접 aws 해당 리전에 들어가서 EC2-ami 카탈로그를 보고 원하는 이미지의 ami값을 골라서 넣어줘야 한다.

resource "aws_instance" "webserverbbb" {
    ami = "ami-0aa7d40eeae50c9a9"
    instance_type = "t2.micro"
    key_name = aws_key_pair.bbb.key_name
}

resource "aws_key_pair" "bbb" {
    key_name = "bbb"
    public_key =file(var.PATH_TO_PUBLIC_KEY)
}

 

init - plan - apply 과정을 끝내면 아래와 같은 창이 뜬다.

 

GUI 상에서 확인해보자.

아래와 같이 설정한 값들을 잘 받아서 EC2 인스턴스가 생성됐다.

EC2- 키페어 부분에 만들었던 bbb 키가 추가되었다.

 

 

++ ) state 파일에 관하여

apply를 한번 하고나니 tfstate 라는 파일이 생성됐다.

상태 파일에는 구성된 AWS 리소스에 관한 정보들이 담겨있다.

이 파일을 기반으로 테라폼은 리소스의 갱신을 한다.

그렇기에 공동으로 작업하기 위해선 상태 파일을 공유해야 한다.

다양한 방법이 있겠지만 AWS를 구축한다면 S3를 사용하는 방법이 많이 사용된다.

 

 

 

 

 

reference

 

클라우드 수업과 별도로 공식문서, 테라폼 업엔러닝 책과 이 블로그들을 참조했다.

공식 튜토리얼

https://developer.hashicorp.com/terraform/language/syntax/configuration

 

Syntax - Configuration Language | Terraform | HashiCorp Developer

Key constructs of the native Terraform language syntax, including identifiers, arguments, blocks, and comments.

developer.hashicorp.com

 

 

https://honglab.tistory.com/114

 

[Terraform on AWS] 테라폼 입문 (in Window)

목차 1. Terraform이란? 2. 실습 환경 설명, terraform 설치 3. IAM User & ACCESS KEY 설정 4. 간단하게 EC2 배포해보기 (+멱등성 체험) 5. Terraform으로 프로비저닝한 리소스들 삭제 1. Terraform이란? 먼저 IaC(Infrastruc

honglab.tistory.com

 

https://blog.naver.com/shino1025/223013663808

 

[Terraform] 대충 쓴 테라폼 입문기

계속 써야지, 써야지 하고 미루다가 드디어 이 주제로 글을 쓰게 되었다. 최근에 다니고 있는 회사의 개발 ...

blog.naver.com