brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Aug 08. 2023

11. 5주 차 - 테라폼-협업,공유 저장소-2022

테라폼 중급을 공부해보자~


<0> 명령서버 생성 

<1> 형상 관리 도구

<2> 실습 - 로컬 작업을 위해 리모트 저장소의 내용을 로컬에 복제 

<3> 실습 - 코드 협업을 위한 1인 2역을 준비 : 복제한 디렉터리 변경 및 추가 복사

<4> 실습 - 두 사람이 작업을 할 때 오류가 나는 경우 시현해 보자.

<5>  풀 리퀘스트 Pull Request = 코드 관리자에게 검토 후 병합을 요청하는 방식

<6> 실습 -  Terraform Cloud  백엔드  사용 , 같이 운영하기

<7> 실습 - 백엔드 구성 = 테라폼 클라우드 공유 저장소 이용해 상태 파일을 저장 사용해야 하는 이유를 알아보자.

<8> 실습 - TFC를 통하여 작업 결과 공유 설정





<0> 명령서버 생성 


https://console.aws.amazon.com/console/home





<1> 형상 관리 도구


1

SVN : 중앙 저장소에서 코드와 히스토리를 관리하는 방식

Git : 분산형 관리 시스템으로 작업 환경에서도 별도로 코드 히스토리를 관리하고 중앙 저장소와 동기화


git 공부자료

https://brunch.co.kr/@topasvga/1821



2

명령서버에서 git 설치 확인

git --version

git version 2.40.1



3

나의 깃 허브에서  Github Token 발급?


https://github.com/topasvga1/topasvga

(암호 입력 gb1!)  <- 실제 암호 아니니 사용하지 마세요^^


개인 아이콘 > Setting > 왼쪽 맨 아래  Developer settings   > Personal access tokens Tockens(classic) > Generate new token  클릭 >  맨 아래 Generate new token (classic)

test-seo1

repo체크

Generate token


(Personal access tokens (classic) 을  복사해두자)




4

책 저자 깃 포크.

https://github.com/terraform101/terraform-aws-collaboration


Fork > Create new Fork



5

깃에서 공유 제외 대상 설정 확인

. gitignore  내용 확인


암호등 보안 파일은 공유되지 않도록 해야 한다.!!

코드 파일 공유 시 깃 관리 대상 제외 →. gitignore 정의

  

. terraform 디렉터리 : init 실행 시 작성되므로 제외   

. tfstate 파일 : 프로비저닝 결과 데이터 소스 정보, 민감 데이터가 포함, 다른 사용자가 같은 State 파일을 사용하는 경우 인프라 불합치 유발   

     tfvars 파일 : 프로비저닝 시 적용할 변수 값을 보관하는 파일로, 작업자마다 별도 변수 사용   

     시크릿 파일 : 인프라 구성에 필요한 시크릿 정보 파일   

     terraformrc 파일 : 작업자의 CLI 설정 파일   



6

제외 대상 설정 된 내용 확인


#. gitignore

# Local. terraform directories

**/.terraform/*


# .tfstate files

*.tfstate

*.tfstate.*


# Crash log files

crash.log

crash.*.log


# Exclude all .tfvars files, which are likely to contain sensitive data, such as

# password, private keys, and other secrets. These should not be part of version 

# control as they are data points which are potentially sensitive and subject 

# to change depending on the environment.

*.tfvars

*.tfvars.json


# no creds

*.pem


# Ignore override files as they are usually used to override resources locally and so

# are not checked in

override.tf

override.tf.json

*_override.tf

*_override.tf.json


# Include override files you do wish to add to version control using negated pattern

# !example_override.tf


# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan

# example: *tfplan*


# Ignore CLI configuration files

.terraformrc

terraform.rc




<2> 실습 - 로컬 작업을 위해 리모트 저장소의 내용을 로컬에 복제 


1

#

MyGit=<각자 자신의 깃허브 계정>

MyGit=topasvga

git clone https://github.com/$MyGit/terraform-aws-collaboration


# 확인

tree terraform-aws-collaboration


terraform-aws-collaboration

├── files

│   └── deploy_app.sh

├── LICENSE

├── main.tf

├── outputs.tf

├── README.md

├── terraform.tfvars.example

└── variables.tf

1 directory, 7 files



cd terraform-aws-collaboration

git remote get-url origin




2

push test?


#

echo "T101 Study" >> test.txt


git add test.txt

git commit -m "first commit"

git push

(정보를 넣어야 하는데 정보를 모른다)



# 우선 Git 자격 증명 설정이 필요하다.

git config --global user.name $MyGit

git config --global user.email <깃허브 가입 이메일주소>

git config --global user.email  topasvga@naver.com

cat ~/.gitconfig



# push 실행을 위해서 로그인 정보 입력

git push

Username for 'https://github.com': <깃허브 계정 정보>

Password for 'https://topasvga@github.com': <토큰 정보>


Username for 'https://github.com': topasvga

Password for 'https://topasvga@github.com': <토큰 정보>




# 로그인 정보 입력 방안2

export GITHUB_USER=topasvga

export GITHUB_TOKEN=<토큰 정보>



3

자신의 깃헙 사이트에서 추가된 파일 확인

새로 고침

test.txt 확인




<3> 실습 - 코드 협업을 위한 1인 2역을 준비 : 복제한 디렉터리 변경 및 추가 복사



1

tom과 jerry 작업 디렉토리 만듬.

원래는 다른 pc이여야 하나 디렉토리만 따로 만들어 사용

terraform-aws-collaboration-tom : tom 작업 디렉터리

terraform-aws-collaboration-jerry : jerry 작업 디렉터리



2

#

cd 

mv terraform-aws-collaboration terraform-aws-collaboration-tom

cp -r terraform-aws-collaboration-tom terraform-aws-collaboration-jerry



3

Push & Pull ?


커밋된 코드는 로컬 저장소에 기록되며 푸시를 하기 전까지는 리모트 저장소에 공유되지 않음 

→ 또한 작업 중 풀을 통해 리모트 저장소의 변경 사항을 로컬 저장소에 반영


cd terraform-aws-collaboration-tom/



tom 디렉터리의 main.tf 파일 코드 내용 수정


...

provider "aws" {

  region = var.region

  default_tags {

    tags = {

      Project = "T101-Study-6week"

    }

  }

}

...



4

수정된 코드를 커밋하고 리모트 저장소에 푸시


#

git remote get-url origin

git add main.tf

git commit -m "add default tags & project name"

git push



자신의 깃헙 사이트에서 main.tf 파일 코드 내용 수정 확인

provider "aws" {

  region = var.region

  default_tags {

    tags = {

      Project = "T101-study1"

    }

  }

}



5

jerry 디렉터리에서 작업


#

cd

cd terraform-aws-collaboration-jerry

git remote get-url origin

git pull

cat main.tf |grep Project

      Project = "T101-study1"


// 원격에 있는 거 가져온다.  톰이 수정한 거로 가져오는 것이다.






<4> 실습 - 두 사람이 작업을 할 때 오류가 나는 경우 시현해 보자.



1

이번에는 tom과 jerry 양쪽에서 default_tags에 Owner 항목을 추가하고 저장 시도



2

jerry 디렉터리의 main.tf 파일 코드 내용 수정


...

provider "aws" {

  region = var.region

  default_tags {

    tags = {

      Project = "T101-Study-6week"

      Owner = "jerry"

    }

  }

}

...



3

수정된 코드를 커밋하고 리모트 저장소에 푸시


#

cd terraform-aws-collaboration-jerry

git add main.tf

git commit -m "add default tags & Owner is jerry"

git push




4

오류가 나는 경우 확인?


tom 디렉터리의 main.tf 파일 코드 내용 수정


cd

cd terraform-aws-collaboration-tom/


...

provider "aws" {

  region = var.region

  default_tags {

    tags = {

      Project = "T101-Study-6week"

      Owner = "tom"

    }

  }

}

...


5

수정된 코드를 커밋하고 리모트 저장소에 푸시.

pull을 안 하고 진행한다.

git add main.tf

git commit -m "add default tags & Owner is tom"


# tom의 루트 모듈 변경 코드를 리모트 저장소에 보낼 때 실패

git push


에러가 발생한다.


 ! [rejected]        main -> main (fetch first)

error: failed to push some refs to 'https://github.com/topasvga/terraform-aws-collaboration'

hint: Updates were rejected because the remote contains work that you do

hint: not have locally. This is usually caused by another repository pushing

hint: to the same ref. You may want to first integrate the remote changes

hint: (e.g., 'git pull ...') before pushing again.

hint: See the 'Note about fast-forwards' in 'git push --help' for details.

[root@myeks2-bastion-EC2 terraform-aws-collaboration-tom]#




6

푸시 전 풀을 먼저 수행해 리모트의 변경 사항을 로컬과 비교한 후 필요할 때 수정해 푸시하는 습관이 필요하다


변경 사항에 충돌이 없는 경우 자동으로 커밋 지점이 병합된다

풀 동작에 충돌이 있을 것으로 가정해 옵션을 붙여 수행 : git rebase


#

git pull --no-rebase


// pull 한 다음에 다시 시도한다.



7

로컬 저장소와 리모트 저장소의 충돌 내용 표기,

 === 위는 로컬 저장소, 아래는 리모트 저장소 내용 

⇒ ‘현재 변경 사항 수락’



#

terraform fmt

git add main.tf

git commit -m "change default tags Owner"

git push


cat main.tf | grep Owner

      Owner="tom"

      Owner="jerry"




<5>  풀 리퀘스트 Pull Request = 코드 관리자에게 검토 후 병합을 요청하는 방식


1

충돌 방지 방법


2

작업자가 코드 수정을 위해 메인과 별개의 브랜치를 생성하고 작업 후 본인의 브랜치를 푸시하고 코드 관리자에게 검토 후 병합을 요청하는 방식


https://brunch.co.kr/@topasvga/765




<6> 실습 -  Terraform Cloud  백엔드  사용 , 같이 운영하기


1

무료 계정으로 저장소 사용할 수 있다.

https://app.terraform.io/session

free account  클릭하여 가입



2

조직을 만든다.

topasvga-org


맨아래 3번째  Create a new organization 


3

테라폼 클라우드를 CLI로 사용할 수 있도록 하자.


terraform login


C:\Users\sss> terraform login

Terraform will request an API token for app.terraform.io using your browser.


If login is successful, Terraform will store the token in plain text in

the following file for use by subsequent commands:

    C:\Users\sss\AppData\Roaming\terraform.d\credentials.tfrc.json


Do you want to proceed?

  Only 'yes' will be accepted to confirm.


  Enter a value: yes



4.  토큰생성


https://app.terraform.io/app/settings/tokens?source=terraform-login


---------------------------------------------------------------------------------


Terraform must now open a web browser to the tokens page for app.terraform.io.


If a browser does not open this automatically, open the following URL to proceed:

    https://app.terraform.io/app/settings/tokens?source=terraform-login



---------------------------------------------------------------------------------


Generate a token using your browser, and copy-paste it into this prompt.


Terraform will store the token in plain text in the following file

for use by subsequent commands:

 C:\Users\sss\AppData\Roaming\terraform.d\credentials.tfrc.json


Token for app.terraform.io:

  Enter a value:  (토큰 입력)




4

이제, 테라폼 클라우드를 CLI로 사용할수 있도록 되었다.



5

토큰 확인

cat ~/.terraform.d/credentials.tfrc.json | jq





<7> 실습 - 백엔드 구성 = 테라폼 클라우드 공유 저장소 이용해 상태 파일을 저장 사용해야 하는 이유를 알아보자.



1

현재 상태 파일을 로컬에서 저장하고 있다.


tom 루트 모듈과 jerry 루트 모듈을 사용해 공통 백엔드 구성과 동작을 확인 

→ 두 작업자가 동일한 AWS 인프라를 프로비저닝하기를 원하는 상황



2

tom 루트 모듈에서 실행


cd 

cd terraform-aws-collaboration-tom


terraform init

terraform plan -var=prefix=dev

terraform apply -auto-approve -var=prefix=dev



  provisioner "remote-exec" {

    inline = [

      "sudo apt -y update",

      "sleep 15",

      "sudo apt -y update",

      "sudo apt -y install apache2",

      "sudo systemctl start apache2",

      "sudo chown -R ubuntu:ubuntu /var/www/html",

      "chmod +x *.sh",

      "PLACEHOLDER=${var.placeholder} WIDTH=${var.width} HEIGHT=${var.height} PREFIX=${var.prefix} ./deploy_app.sh",

      "sudo apt -y install cowsay",

      "cowsay Mooooooooooo!",

    ]

    connection {

      type        = "ssh"

      user        = "ubuntu"

      private_key = tls_private_key.hashicat.private_key_pem

      host        = aws_eip.hashicat.public_ip

    }

  }

}




# 확인

terraform workspace list

terraform state list


ls terraform.tfstate*

상태 파일은 로컬에 있다.



terraform output




3

jerry 루트 모듈에서 실행 : plan 결과가 어떤가요?


#

cd 

cd terraform-aws-collaboration-jerry


# plan 결과가 어떤가요?

terraform init && terraform plan -var=prefix=dev



Plan: 12 to add, 0 to change, 0 to destroy.



결과?

제리도 동일한  코드로 플랜하면 만들려고 한다.

중복이다.

그래서 상태 저장소에  상태파일을 같이 공유해 써야 한다.

톰이 먼저 만들었다.

로컬 상태 파일을 사용해서 문제가 되는 것이다.




<8> 실습 - TFC를 통하여 작업 결과 공유 설정


1

TFC의 workspaces는 CLI에서의 workspace처럼 테라폼 구성과는 별개로 State를 관리하는 단위다



2

cd 

cd terraform-aws-collaboration-tom


tom 루트 모듈에 main.tf 파일 수정


terraform {

  cloud {

    organization = "<MY_ORG_NAME>"         # 생성한 ORG 이름 지정 , topasvga-org

    hostname     = "app.terraform.io"      # default


    workspaces {

      name = "terraform-aws-collaboration"  # 없으면 생성됨

    }

  }

...



3

terraform init

yes


# 파일 내용이 어떤가요?

ls -al terraform.tfstate*

-rw-r--r-- 1 root root     0 Aug  8 13:26 terraform.tfstate

-rw-r--r-- 1 root root 30477 Aug  8 13:26 terraform.tfstate.backup

파일 0바이트.

로컬 파일을 사용하지 않는다.


cat terraform.tfstate





4

TFC 전용 

Workspace State 백엔드 역할만 수행) 확인 → 선택 후 좌측에 Settings 클릭 → General


5

실행 모드 변경 :

Execution Mode 에서 Local 선택 → 하단의 Save settings 클릭하여 변경 적용


Remote : 테라폼 실행을 Terraform Cloud에서 수행

Local : 테라폼 실행은 작업자 환경 또는 연결된 외부 환경에서 실행해 State만을 동기화

Agent : 테라폼 실행을 사용자 지정 Agent(설치된 서버 환경)에서 수행 (Business 플랜에서 활성화)


6

이후 [States] 탭에서 terraform init을 통해 마이그레이션된 State 업로드 정보 확인



7

백엔드 저장소 동작 확인


# plan 결과가 어떤가요?

상태 파일들 다 삭제하고 플랜 해보자.


rm -rf terraform.tfstate*

terraform plan -var=prefix=dev


없으면 만들어 진다고 나와야 하는데  변화가 없다.

No changes. Your infrastructure matches the configuration.


로컬 상태 파일을 사용하지 않는것이다.




8

push 


git add main.tf

git commit -m "tfc state"

git push



9

jerry 루트 모듈에서 확인


#

cd 

cd terraform-aws-collaboration-jerry

git pull



# plan 결과 어떻게 되나요?

terraform init

terraform plan -var=prefix=dev

No changes. Your infrastructure matches the configuration.


// 제리도  테라폼 클라우드 사용하는것으로 변경되었다.

공유 저장소를 사용하기 때문에 더 이상 변경이 없다.




다음과정

https://brunch.co.kr/@topasvga/3396



전체 보기

https://brunch.co.kr/@topasvga/3347

다음은 주말 CloudNet 테라폼 스터디 내용 참고하여  정리한 부분입니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863  



https://brunch.co.kr/@topasvga/3385


감사합니다.



브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari