SlideShare a Scribd company logo
1 of 29
테라폼으로 글로벌 서비스
구성
- DRY 체험기 -
devops@mykoon.com
Spoon Radio Infra Member
● 노가다를 싫어하는 노땅 엔지니어 2명
○ 최상기(Martin): https://www.linkedin.com/in/sanggi-choi/
○ 백영진(Paul): https://www.linkedin.com/in/youngjin-baek-8a2a74a4/
● 묵묵히 열심히 겁나게 달려주는 엔지니어 1명
○ 박민호(Ash): https://www.linkedin.com/in/park-minho-4896b7117/
Agenda
● Spoon Radio 소개
● 요구 사항
● 인프라 구성 도구
● 코드 중복 극복기 (DRY Journey)
○ Phase 1: Terraform
○ Phase 2: Terraform Module
○ Phase 3: Terragrunt
○ 고민
○ 숙제
● 정리
SPOON RADIO
● 개요: 개인 오디오 라이브 스트리밍 모바일 플랫폼
● 특징: 10 ~ 20대를 타겟팅 한 모바일 미디어 채널
● 2016년(한국), 2017년(인도네시아/베트남), 2018년(일본/중동 GCC 5개국)
● 글로벌 다운로드 900만 / 글로벌 MAU 170만
6개월 간의 중복 코드 탈출기(ing)
● WET: Write Everything Twice
○ 중복, 반복된 코드
○ 수정 및 재 활용 하는데 많은 비용 발생
● DRY: Don't Repeat Yourself
○ 품질과 무결성 확보
○ 읽기 쉽고
○ 재활용 가능
○ 수정 및 활용 하는데 비용이 낮음.
요구 사항
● 보통 인프라 구조는 거의 유사하지만, 아주 약간 다른 환경 구성 관리를 해야
함.
○ multiple aws accounts & region , environments,
○ aws resource(IAM, VPC, Subnet, RDS, EC2, Aurora, ALB, Lambda, S3, Route53 and so on.)
=> 5개국 서비스 구성시 15개의 유사 인프라 구성과 관리
● 기존 Legacy Infra를 Code 기반으로 자동화
○ AWS Well-Architected & ISMS & ISO27001 대응 인프라 구성
○ 생산성이 높은 인프라 환경 구성
인프라 구성 도구
Code Repository
Infrastructure
Provisioning
Image
Management
Configuration
Management
CI/CD
Code Repository
(Terraform, Packer,
AWX, Ansible,
Dockerfile..etc)
AWS Infrastructure
(VPC, Subnet,
Security Group,
IAM, S3.. etc)
AWS AMI Base
Image
(Amazon Linux,
Ubuntu,
CentOS..etc)
Software
Provisioning
(Nginx,Python,Java,
Docker..etc)
Continuous
Integration &
Delivery
(Terraform, Packer,
Application, Web)
Terragrunt
Phase 1 - Terraform
● IaC - 인프라 생성, 변경, 설정을 코드 관리
○ 비용의 감소(돈, 인력, 노력 등)
○ 빠른 실행 속도
○ 위험 관리
○ 불확실성에 대한 유연함 - 아는 만큼 보이고, 처음 부터 완벽할 수 없다.
● Terraform
○ Terraform은 HashiCprop에서 만든 오픈 소스 도구이며,
인프라를 코드 형태로 정의하는 간편한 선언형 프로그래밍 언어
■ Multi Provider
■ Large Community
○ 그냥 해 보고 싶었다.
Phase 1 - 시작
● VPC
● Subnet
● Route Table
● IGW
● NAT
Phase 1 - 단순 리소스 나열
# kor/main.tf
provider "aws" {
region = "ap-northeast-2"
access_key ="XXXXXXXXXXXXXXXX"
secert_key ="XXXXXXXXXXXXXXXX"
}
resource "aws_vpc" "test-vpc" {
cidr_block = "10.1.0.0/16"
instance_tenancy = "default"
enable_dns_support = "true"
enable_dns_hostnames = "true"
enable_classiclink = "false"
tags {
Name = "test-vpc"
}
}
resource "aws_subnet" "public-subnet-2a" {
vpc_id =
"${aws_vpc.test-vpc.id}"
cidr_block = "10.1.1.0/24"
map_public_ip_on_launch = "true"
availability_zone = "ap-northeast-2a"
tags {
Name = "public-subnet-2a"
}
}
resource "aws_subnet" "private-subnet-2a" {
vpc_id =
"${aws_vpc.test-vpc.id}"
cidr_block = "10.1.2.0/24"
map_public_ip_on_launch = "false"
availability_zone = "ap-northeast-2a"
tags {
Name = "private-subnet-2a"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = "${aws_vpc.test-vpc.id}"
tags {
Name = "internet-gateway"
}
}
resource "aws_route_table" "rt1" {
vpc_id = "${aws_vpc.test-vpc.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.gw.id}"
}
tags {
Name = "Default"
}
}
resource "aws_route_table_association"
"association-subnet" {
subnet_id = "${aws_subnet.public-1.id}"
route_table_id = "${aws_route_table.rt1.id}"
}
output "vpc-id" {
value = "${aws_vpc.test-vpc.id}"
}
output "vpc-public-subnet-cidr" {
value =
"${aws_subnet.public-subnet-2a.cidr_block}"
}
output "vpc-public-subnet-id" {
value = "${aws_subnet.public-subnet-2a.id}"
}
output "vpc-private-subnet-cidr" {
value =
"${aws_subnet.private-subnet-2a.cidr_block}"
}
output "vpc-private-subnet-id" {
value = "${aws_subnet.private-subnet-2a.id}"
}
Phase 1 - main.tf 중복
KR JP IN VE MENA
+ PRD
- main.tf
+ STG
- main.tf
+ DEV
- main.tf
+ PRD
- main.tf
+ STG
- main.tf
+ DEV
- main.tf
+ PRD
- main.tf
+ STG
- main.tf
+ DEV
- main.tf
+ PRD
- main.tf
+ STG
- main.tf
+ DEV
- main.tf
+ PRD
- main.tf
+ STG
- main.tf
+ DEV
- main.tf
● 5개 국가, 3개의 인프라 환경 => 총 15개의 인프라 환경을 구성 관리해야 함.
○ 국가, 환경은 다르지만 동일한 인프라 구조를 만들기 위한 중복되는 옵션의 resource가 다수
발생.
○ 대략 100 ~ 200 line 수준의 main.tf WET Code 발생.
Phase 1 - 결국
● 단순 리소스 나열만으로는 15벌 인프라 전개 불가능
○ 재활용이 불가능
○ 비슷한 리소스의 대량 중복 발생
○ 유지 보수 불가능
○ 이렇게 할 거면 Hands - On과 차이가....
Phase 2 - Terraform Module
● Data를 변수 처리한 리소스 구성 파일 묶음.
○ 비슷한 리소스를 반복 정의하는 고통에서 벗어날 수 있다.
○ 사용자 정의 모듈 만들어 활용
○ 외부에서 이미 잘 만들어둔 모듈 활용
■ https://registry.terraform.io/
■ https://github.com/cloudposse
■ https://github.com/terraform-aws-modules
○ 리소스에는 versioning이 안되지만, 모듈에는 버저닝 가능
-> 모듈간 독립성 확보(의존성 제거)
Phase 2 - 시도
# terraform-aws-vpc/main.tf
locals {
max_subnet_length = max(
length(var.private_subnets),
length(var.elasticache subnets),
length(var.database_subnets),
length(var.redshift_subnets),
)
nat_gateway_count = var.single_nat_gateway ? 1 :
var.one_nat_gateway_per_az ? length(var.azs) :
local.max_subnet_length
………… 길어요...
# prd-kr/main.tf
terraform {
backend "s3" {
bucket = "backend-bucket"
key = "prd-kr-vpc/terraform.tfstate"
region = "ap-northeast-2"
profile = "prd-kr"
}
}
provider aws {
region = "ap-northeast-2"
profile = "prd"
}
module "network" {
source = "../modules/network"
name = "${var.name}"
cidr = "${var.cidr}"
azs = "${var.azs}"
public_subnets = "${var.public_subnets}"
env = "${var.env}"
}
# prd-kr/vars.tf
variable name {
type = "string"
default = ""
}
variable cidr {
type = "string"
default = "0.0.0.0/0"
}
variable public_subnets {
type = "list"
default = ["0.0.0.0/0"]
}
variable private_subnets {
type = "list"
default = ["0.0.0.0/0"]
}
variable azs {
type = "list"
default = [""]
}
# prd-kr/terraform.tfvars
name = "prd-kor-vpc"
cidr = "10.1.0.0/16"
public_subnets = ["10.1.1.0/24", ...]
public_subnets = ["10.1.2.0/24", ...]
asz = ["ap-northeast-2a", ...]
env = "prd-kor
vars.tf
Duplicated
main.tf
Duplicated
Phase 2 - Repeat Itself, Again
● module을 사용하면서 resource는 재활용이 가능해
졌지만, root module을 참조하는 sub module과 변수
정의 부분은 각 환경별 중복이 발생
● terraform.tfvars을 제외한 곳에서 WET code 발생
# jpn/terraform.tfvars
name = "prd-jpn-vpc"
cidr = "10.2.0.0/16"
public_subnets = ["10.2.0.0/24", ...]
public_subnets = ["10.2.1.0/24", ...]
asz = ["ap-northeast-2a", ...]
env = "prd-kor
# kor/terraform.tfvars
name = "prd-kor-vpc"
cidr = "10.1.0.0/16"
public_subnets = ["10.1.1.0/24", ...]
public_subnets = ["10.1.2.0/24", ...]
asz = ["ap-northeast-2a", ...]
env = "prd-kor
# kor/main.tf
module "network" {
source = "../modules/network"
name = "${var.name}"
cidr = "${var.cidr}"
azs = "${var.azs}"
public_subnets = "${var.public_subnets}"
env = "${var.env}"
}
# kor/vars.tf
variable name {
type = "string"
default = ""
}
variable cidr {
type = "string"
default = "0.0.0.0/0"
}
# jpn/main.tf
module "network" {
source = "../modules/network"
name = "${var.name}"
cidr = "${var.cidr}"
azs = "${var.azs}"
public_subnets = "${var.public_subnets}"
env = "${var.env}"
}
# jpn/vars.tf
variable name {
type = "string"
default = ""
}
variable cidr {
type = "string"
default = "0.0.0.0/0"
}
Phase 2 - 세상에 공짜는 없다.
● multiple env에서 그래도 중복 발생(main.tf, var.tf)
○ 5개 국가, 3개 환경 구성에 대한 중복은 그대로
○ global, local 변수 정의 관리 불편
● 오픈소스 모듈도 결국 내 입맛에 맞게 수정
○ 조금만 바꿔도 삭제 후 재 생성 ㅜㅜ
■ 요구 사항에 맞게 Lifecycle 관리 추가
○ resource 생성을 모듈 하위에서 생성하기에 수정하기가 불가함
○ 결국에 오픈소스 전체 코드 분석 후 수정함
Phase 3 - Terragrunt
● gruntworks.io에서 개발하고, Terraform만으로는 부족한 기능 보완
● 단순한 인프라는 Terraform으로도 충분하다.
그러나 인프라 구성이 커질 수록 모듈간의 연관 관계 및 중복 발생
● Orchestration = Terragrunt
○ 모듈 간의 코드 중복을 최소화
○ 모듈 간의 종속 관계 제거
Gruntwork.io
Terragrunt 기본 구조
● /terraform.tfvars
○ terragrunt의
환경설정
● /globals.tfvars
○ root module
○ root vars
● locals.tfvars
○ sub module
○ sub vars
● terraform.tfvars
○ 각각의 vars
terragrunt = {
….
terraform {
extra_arguments "-var-file" {
commands = ["${get_terraform_commands_that_need_vars()}"]
optional_var_files = [
"${get_tfvars_dir()}/${find_in_parent_folders("globals.tfvars", "ignore")}",
"${get_tfvars_dir()}/${find_in_parent_folders("locals.tfvars", "ignore")}"
]
}
}
}
namespace = "prod"
# dynamodb & s3
bucket = "prod-terraform-state"
config_region = "ap-northeast-2"
dynamodb_table = "prod-terraform-db"
stage = "kor"
aws_region = "ap-northeast-2"
# remote state key
vpc_remote_state_key = "prod/kor/terraform.tfstate"
terragrunt = {
terraform {
source = "git::ssh/spooncast/terraform-service-repo.git?ref=release/v0.0.1//bastion"
}
include = {
path = "${find_in_parent_folders()}"
}
}
name = "bastion"
instance_type = "t2.micro"
cidr_office = "xxx.xxx.xxx.xxx/32"
코드와 데이터의 분리(Data Driven Design)
# prod/main.tf
terraform {
# The configuration for this backend will be filled in by
Terragrunt
backend "s3" {}
}
provider aws {
region = "${var.region}"
profile = "${var.profile}"
}
module "network" {
source = "terraform-aws-modules/vpc/aws"
name = "${var.name}"
cidr = "${var.cidr}"
azs = "${var.azs}"
public_subnets = "${var.public_subnets}"
env = "${var.country}"
}
# global.tfvars
profile = "prod"
# prod/local.tfvars
region = "ap-northeast-2"
country = "kr"
# prod/terraform.tfvars
terragrunt = {
terraform {
source = "network"
}
include = {
path = "${find_in_parent_folders()}"
}
}
name = "vpc-prd-kor"
cidr = "10.1.0.0/16"
azs = ["ap-northeast-2a", "ap-northeast-2b",
"ap-northeast-2c"]
public_subnets = ["10.1.1.0/24", "10.1.2.0/24,
"10.1.3.0/24]
# prod/local.tfvars
region = "ap-northeast-1"
country = "jp"
# prod/terraform.tfvars
terragrunt = {
terraform {
source = "network"
}
include = {
path = "${find_in_parent_folders()}"
}
}
name = "vpc-prd-jp"
cidr = "10.2.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1b",
"ap-northeast-1c"]
public_subnets = ["10.2.1.0/24", "10.2.2.0/24,
"10.2.3.0/24]
# prod/local.tfvars
region = "ap-south-1"
country = "mena"
# prod/terraform.tfvars
terragrunt = {
terraform {
source = "network"
}
include = {
path = "${find_in_parent_folders()}"
}
}
name = "vpc-prd-mena"
cidr = "10.3.0.0/16"
azs = ["ap-south-1a", "ap-south-1b",
"ap-south-1c"]
public_subnets = ["10.3.1.0/24", "10.3.2.0/24,
"10.3.3.0/24]
output 참조
#local.tfvars
namespace = "prod"
stage = "kor"
aws_region = "ap-northeast-2"
# remote state key
vpc_remote_state_key = "prod/kor/xxx/terraform.tfstate"
#data.tf
data "terraform_remote_state" "vpc" {
backend = "s3"
config {
bucket = "${var.bucket}"
key = "${var.vpc_remote_state_key}"
region = "${var.config_region}"
encrypt = true
dynamodb_table = "${var.dynamodb_table}"
acl = "bucket-owner-full-control"
}
# https://www.terraform.io/docs/providers/consul/index.html
backend = "consul"
config {
address = "${var.consul_address}"
path = "${var.vpc_remote_state_key}"
datacenter = "${var.datacenter}"
}
}
# global.tfvars
profile = "prod"
Dependencies between modules
terragrunt = {
terraform {
source = "../../../modules//services//was"
}
include = {
path = "${find_in_parent_folders()}"
}
dependencies {
paths = ["../network"]
}
}
...
주의 (主義)
Terragrunt up-all 실행시 Dependencies까지 함께
생성됨.
하지만 all로 생성된 모듈을 destroy 을 할 경우
같이 생성 된 dependencies 까지 삭제 함.
Terraform & Terragrunt Code Version
terragrunt = {
terraform {
source =
"git::ssh://git@github.com/tf-service-repo.git?ref=rel
ease/v0.0.1//api"
}
include = {
path = "${find_in_parent_folders()}"
}
...
module "api" {
source =
"git::ssh://git@github.com//tf-module-repo.git?ref=r
elease/v0.0.1//ec2"
instance_count = "${var.instance_count}"
instance_type = "${var.instance_type}"
associate_public_ip_address =
"${var.associate_public_ip_address}"
subnet_ids =
["${data.aws_subnet.subnet.*.id}"]
...
Terraform Module Layer Service Layer Terragrunt Layer
Terraform & Terragrunt Structure
Terraform Module Repo Service Repo Terragrunt Repo
고민
● Terraform 통한 인프라 구성이 빠르지 않다
○ Terraform 코드 개발 및 검증
○ Terraform Learning cove
○ 손으로 작업 했던 경험
○ 이상과 현실
● Terragrunt도 사용해야 한다.
○ Terraform Enterprise에는 Terragrunt에서 제공하는 대분분의 기능을 제공한다던데...
손은 (눈)코드보다 빠르다
숙제
● Terraform 모듈 테스트 및 검증
○ CI pipeline 통한 모듈 테스트 도입
● PRD 환경 적용 후 리소스 삭제 방지
○ Terraform Lifecycle 설정
○ plan 통한 생성 및 삭제 리뷰 프로세스 수립
● tfstate 파일 시각화
○ tfstate 변경 이력 관리 (Terraboard 도입)
● Data Security (ssh key, password)
○ Vault, Consul 통한 데이터 보안
정리
● “상용 수준 인프라를 구성하고 운영 하는 것은 매우 어렵다”것 인지 하자.
● (AWS) 기본 디자인을 잘 하자.
● DRY를 실천하기 위해 노력 하자.
○ 한 곳에 너무 많은 리소스를 정의 하지 말자.
○ 중복을 최소화하고, 최대한 작게 서로 독립적으로 단순하게 구성 하자.
● 팀에서의 강력한 의지가 없다면 하지 말자.. (아무리 좋아도 관리 안되면 허사)
● 불확성(외부 요구 사항)에 대한 보다 유연한 대응을 위해 노력해야 합니다.
Spoon Radio Infra Member
● 노가다를 싫어하는 노땅 엔지니어 2명
● 묵묵히 열심히 달려주는 엔지니어 1명
● 그리고 함께 경험 하실 분 모십니다.
Reference
● https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
● https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/
● https://blog.gruntwork.io/5-lessons-learned-from-writing-over-300-000-lines-of-infrastructure-code-36ba7fadeac1
● https://www.slideshare.net/AntonBabenko/terraform-modules-and-some-of-bestpractices-march-2019
● https://qiita.com/billthelizard/items/9e113f3f569db4f569a5
● https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/2.7.0
● https://caylent.com/devops-and-dry/
● https://techblog.gumgum.com/articles/introducing-terraform-at-gumgum
● https://blog.gruntwork.io/
● https://www.slideshare.net/AntonBabenko/terraform-modules-and-some-of-bestpractices-march-2019
● https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/
● https://www.44bits.io/ko/post/terraform_introduction_infrastrucute_as_code
감사합니다.

More Related Content

What's hot

AWS Lambda 내부 동작 방식 및 활용 방법 자세히 살펴 보기 - 김일호 솔루션즈 아키텍트 매니저, AWS :: AWS Summit ...
AWS Lambda 내부 동작 방식 및 활용 방법 자세히 살펴 보기 - 김일호 솔루션즈 아키텍트 매니저, AWS :: AWS Summit ...AWS Lambda 내부 동작 방식 및 활용 방법 자세히 살펴 보기 - 김일호 솔루션즈 아키텍트 매니저, AWS :: AWS Summit ...
AWS Lambda 내부 동작 방식 및 활용 방법 자세히 살펴 보기 - 김일호 솔루션즈 아키텍트 매니저, AWS :: AWS Summit ...Amazon Web Services Korea
 
Secure Virtual Private Cloud(VPC)를 활용한 보안성 강화와 비용절감 - 안경진 부장, 포티넷 코리아 :: AWS ...
Secure Virtual Private Cloud(VPC)를 활용한 보안성 강화와 비용절감 - 안경진 부장, 포티넷 코리아 :: AWS ...Secure Virtual Private Cloud(VPC)를 활용한 보안성 강화와 비용절감 - 안경진 부장, 포티넷 코리아 :: AWS ...
Secure Virtual Private Cloud(VPC)를 활용한 보안성 강화와 비용절감 - 안경진 부장, 포티넷 코리아 :: AWS ...Amazon Web Services Korea
 
Serverless with IAC - terraform과 cloudformation 비교
Serverless with IAC - terraform과 cloudformation 비교Serverless with IAC - terraform과 cloudformation 비교
Serverless with IAC - terraform과 cloudformation 비교재현 신
 
K8s, Amazon EKS - 유재석, AWS 솔루션즈 아키텍트
K8s, Amazon EKS - 유재석, AWS 솔루션즈 아키텍트K8s, Amazon EKS - 유재석, AWS 솔루션즈 아키텍트
K8s, Amazon EKS - 유재석, AWS 솔루션즈 아키텍트Amazon Web Services Korea
 
[AWS Builders] AWS와 함께하는 클라우드 컴퓨팅
[AWS Builders] AWS와 함께하는 클라우드 컴퓨팅[AWS Builders] AWS와 함께하는 클라우드 컴퓨팅
[AWS Builders] AWS와 함께하는 클라우드 컴퓨팅Amazon Web Services Korea
 
AWS 기반 대규모 트래픽 견디기 - 장준엽 (구로디지털 모임) :: AWS Community Day 2017
AWS 기반 대규모 트래픽 견디기 - 장준엽 (구로디지털 모임) :: AWS Community Day 2017AWS 기반 대규모 트래픽 견디기 - 장준엽 (구로디지털 모임) :: AWS Community Day 2017
AWS 기반 대규모 트래픽 견디기 - 장준엽 (구로디지털 모임) :: AWS Community Day 2017AWSKRUG - AWS한국사용자모임
 
Working with Terraform on Azure
Working with Terraform on AzureWorking with Terraform on Azure
Working with Terraform on Azuretombuildsstuff
 
Introduction To Terraform
Introduction To TerraformIntroduction To Terraform
Introduction To TerraformSasitha Iresh
 
Building infrastructure as code using Terraform - DevOps Krakow
Building infrastructure as code using Terraform - DevOps KrakowBuilding infrastructure as code using Terraform - DevOps Krakow
Building infrastructure as code using Terraform - DevOps KrakowAnton Babenko
 
A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices Nebulaworks
 
Fargate 를 이용한 ECS with VPC 1부
Fargate 를 이용한 ECS with VPC 1부Fargate 를 이용한 ECS with VPC 1부
Fargate 를 이용한 ECS with VPC 1부Hyun-Mook Choi
 
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015 AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015 Amazon Web Services Korea
 
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중Amazon Web Services Korea
 
AWS Direct Connect 및 VPN을 이용한 클라우드 아키텍쳐 설계:: Steve Seymour :: AWS Summit Seou...
AWS Direct Connect 및 VPN을 이용한 클라우드 아키텍쳐 설계:: Steve Seymour :: AWS Summit Seou...AWS Direct Connect 및 VPN을 이용한 클라우드 아키텍쳐 설계:: Steve Seymour :: AWS Summit Seou...
AWS Direct Connect 및 VPN을 이용한 클라우드 아키텍쳐 설계:: Steve Seymour :: AWS Summit Seou...Amazon Web Services Korea
 
Microsoft Azure IaaS and Terraform
Microsoft Azure IaaS and TerraformMicrosoft Azure IaaS and Terraform
Microsoft Azure IaaS and TerraformAlex Mags
 
Terraform 0.12 + Terragrunt
Terraform 0.12 + TerragruntTerraform 0.12 + Terragrunt
Terraform 0.12 + TerragruntAnton Babenko
 
An introduction to AWS CloudFormation - Pop-up Loft Tel Aviv
An introduction to AWS CloudFormation - Pop-up Loft Tel AvivAn introduction to AWS CloudFormation - Pop-up Loft Tel Aviv
An introduction to AWS CloudFormation - Pop-up Loft Tel AvivAmazon Web Services
 

What's hot (20)

AWS Lambda 내부 동작 방식 및 활용 방법 자세히 살펴 보기 - 김일호 솔루션즈 아키텍트 매니저, AWS :: AWS Summit ...
AWS Lambda 내부 동작 방식 및 활용 방법 자세히 살펴 보기 - 김일호 솔루션즈 아키텍트 매니저, AWS :: AWS Summit ...AWS Lambda 내부 동작 방식 및 활용 방법 자세히 살펴 보기 - 김일호 솔루션즈 아키텍트 매니저, AWS :: AWS Summit ...
AWS Lambda 내부 동작 방식 및 활용 방법 자세히 살펴 보기 - 김일호 솔루션즈 아키텍트 매니저, AWS :: AWS Summit ...
 
Final terraform
Final terraformFinal terraform
Final terraform
 
Secure Virtual Private Cloud(VPC)를 활용한 보안성 강화와 비용절감 - 안경진 부장, 포티넷 코리아 :: AWS ...
Secure Virtual Private Cloud(VPC)를 활용한 보안성 강화와 비용절감 - 안경진 부장, 포티넷 코리아 :: AWS ...Secure Virtual Private Cloud(VPC)를 활용한 보안성 강화와 비용절감 - 안경진 부장, 포티넷 코리아 :: AWS ...
Secure Virtual Private Cloud(VPC)를 활용한 보안성 강화와 비용절감 - 안경진 부장, 포티넷 코리아 :: AWS ...
 
Serverless with IAC - terraform과 cloudformation 비교
Serverless with IAC - terraform과 cloudformation 비교Serverless with IAC - terraform과 cloudformation 비교
Serverless with IAC - terraform과 cloudformation 비교
 
K8s, Amazon EKS - 유재석, AWS 솔루션즈 아키텍트
K8s, Amazon EKS - 유재석, AWS 솔루션즈 아키텍트K8s, Amazon EKS - 유재석, AWS 솔루션즈 아키텍트
K8s, Amazon EKS - 유재석, AWS 솔루션즈 아키텍트
 
[AWS Builders] AWS와 함께하는 클라우드 컴퓨팅
[AWS Builders] AWS와 함께하는 클라우드 컴퓨팅[AWS Builders] AWS와 함께하는 클라우드 컴퓨팅
[AWS Builders] AWS와 함께하는 클라우드 컴퓨팅
 
AWS 기반 대규모 트래픽 견디기 - 장준엽 (구로디지털 모임) :: AWS Community Day 2017
AWS 기반 대규모 트래픽 견디기 - 장준엽 (구로디지털 모임) :: AWS Community Day 2017AWS 기반 대규모 트래픽 견디기 - 장준엽 (구로디지털 모임) :: AWS Community Day 2017
AWS 기반 대규모 트래픽 견디기 - 장준엽 (구로디지털 모임) :: AWS Community Day 2017
 
Working with Terraform on Azure
Working with Terraform on AzureWorking with Terraform on Azure
Working with Terraform on Azure
 
Introduction To Terraform
Introduction To TerraformIntroduction To Terraform
Introduction To Terraform
 
Terraform
TerraformTerraform
Terraform
 
Building infrastructure as code using Terraform - DevOps Krakow
Building infrastructure as code using Terraform - DevOps KrakowBuilding infrastructure as code using Terraform - DevOps Krakow
Building infrastructure as code using Terraform - DevOps Krakow
 
A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices
 
Fargate 를 이용한 ECS with VPC 1부
Fargate 를 이용한 ECS with VPC 1부Fargate 를 이용한 ECS with VPC 1부
Fargate 를 이용한 ECS with VPC 1부
 
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015 AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
 
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
 
AWS Direct Connect 및 VPN을 이용한 클라우드 아키텍쳐 설계:: Steve Seymour :: AWS Summit Seou...
AWS Direct Connect 및 VPN을 이용한 클라우드 아키텍쳐 설계:: Steve Seymour :: AWS Summit Seou...AWS Direct Connect 및 VPN을 이용한 클라우드 아키텍쳐 설계:: Steve Seymour :: AWS Summit Seou...
AWS Direct Connect 및 VPN을 이용한 클라우드 아키텍쳐 설계:: Steve Seymour :: AWS Summit Seou...
 
Microsoft Azure IaaS and Terraform
Microsoft Azure IaaS and TerraformMicrosoft Azure IaaS and Terraform
Microsoft Azure IaaS and Terraform
 
Terraform 0.12 + Terragrunt
Terraform 0.12 + TerragruntTerraform 0.12 + Terragrunt
Terraform 0.12 + Terragrunt
 
Terraform on Azure
Terraform on AzureTerraform on Azure
Terraform on Azure
 
An introduction to AWS CloudFormation - Pop-up Loft Tel Aviv
An introduction to AWS CloudFormation - Pop-up Loft Tel AvivAn introduction to AWS CloudFormation - Pop-up Loft Tel Aviv
An introduction to AWS CloudFormation - Pop-up Loft Tel Aviv
 

Similar to Configuring global infrastructure in terraform

Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018Amazon Web Services Korea
 
Terraform을 이용한 Infrastructure as Code 실전 구성하기
Terraform을 이용한 Infrastructure as Code 실전 구성하기Terraform을 이용한 Infrastructure as Code 실전 구성하기
Terraform을 이용한 Infrastructure as Code 실전 구성하기JeongHun Byeon
 
Apache ZooKeeper 소개
Apache ZooKeeper 소개Apache ZooKeeper 소개
Apache ZooKeeper 소개중선 곽
 
Klug pacemaker the opensource high-availability_1.0_f
Klug pacemaker the opensource high-availability_1.0_fKlug pacemaker the opensource high-availability_1.0_f
Klug pacemaker the opensource high-availability_1.0_f동현 김
 
제3회난공불락 오픈소스 인프라세미나 - Pacemaker
제3회난공불락 오픈소스 인프라세미나 - Pacemaker제3회난공불락 오픈소스 인프라세미나 - Pacemaker
제3회난공불락 오픈소스 인프라세미나 - PacemakerTommy Lee
 
Programming Cascading
Programming CascadingProgramming Cascading
Programming CascadingTaewook Eom
 
[오픈소스컨설팅] Open stack kilo with DVR_CEPH_v1.1
[오픈소스컨설팅] Open stack kilo with DVR_CEPH_v1.1[오픈소스컨설팅] Open stack kilo with DVR_CEPH_v1.1
[오픈소스컨설팅] Open stack kilo with DVR_CEPH_v1.1Ji-Woong Choi
 
Openstack live migration
Openstack live migrationOpenstack live migration
Openstack live migrationymtech
 
NodeJs로 디바이스 통신하기
NodeJs로 디바이스 통신하기NodeJs로 디바이스 통신하기
NodeJs로 디바이스 통신하기TaeYoung Kim
 
[드론] 펌웨어 분석 [2015.5.23]
[드론] 펌웨어 분석 [2015.5.23][드론] 펌웨어 분석 [2015.5.23]
[드론] 펌웨어 분석 [2015.5.23]chcbaram
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSCirculus
 
하이퍼레저 페이지 단위 블록 조회
하이퍼레저 페이지 단위 블록 조회하이퍼레저 페이지 단위 블록 조회
하이퍼레저 페이지 단위 블록 조회wonyong hwang
 
[232] 수퍼컴퓨팅과 데이터 어낼리틱스
[232] 수퍼컴퓨팅과 데이터 어낼리틱스[232] 수퍼컴퓨팅과 데이터 어낼리틱스
[232] 수퍼컴퓨팅과 데이터 어낼리틱스NAVER D2
 
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안Jeongsang Baek
 
[오픈소스컨설팅] 스카우터 사용자 가이드 2020
[오픈소스컨설팅] 스카우터 사용자 가이드 2020[오픈소스컨설팅] 스카우터 사용자 가이드 2020
[오픈소스컨설팅] 스카우터 사용자 가이드 2020Ji-Woong Choi
 
[오픈소스컨설팅]Nginx jboss 연동가이드__v1
[오픈소스컨설팅]Nginx jboss 연동가이드__v1[오픈소스컨설팅]Nginx jboss 연동가이드__v1
[오픈소스컨설팅]Nginx jboss 연동가이드__v1Ji-Woong Choi
 
[225]빅데이터를 위한 분산 딥러닝 플랫폼 만들기
[225]빅데이터를 위한 분산 딥러닝 플랫폼 만들기[225]빅데이터를 위한 분산 딥러닝 플랫폼 만들기
[225]빅데이터를 위한 분산 딥러닝 플랫폼 만들기NAVER D2
 
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석GangSeok Lee
 

Similar to Configuring global infrastructure in terraform (20)

Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 
Terraform을 이용한 Infrastructure as Code 실전 구성하기
Terraform을 이용한 Infrastructure as Code 실전 구성하기Terraform을 이용한 Infrastructure as Code 실전 구성하기
Terraform을 이용한 Infrastructure as Code 실전 구성하기
 
Apache ZooKeeper 소개
Apache ZooKeeper 소개Apache ZooKeeper 소개
Apache ZooKeeper 소개
 
Klug pacemaker the opensource high-availability_1.0_f
Klug pacemaker the opensource high-availability_1.0_fKlug pacemaker the opensource high-availability_1.0_f
Klug pacemaker the opensource high-availability_1.0_f
 
제3회난공불락 오픈소스 인프라세미나 - Pacemaker
제3회난공불락 오픈소스 인프라세미나 - Pacemaker제3회난공불락 오픈소스 인프라세미나 - Pacemaker
제3회난공불락 오픈소스 인프라세미나 - Pacemaker
 
Programming Cascading
Programming CascadingProgramming Cascading
Programming Cascading
 
[오픈소스컨설팅] Open stack kilo with DVR_CEPH_v1.1
[오픈소스컨설팅] Open stack kilo with DVR_CEPH_v1.1[오픈소스컨설팅] Open stack kilo with DVR_CEPH_v1.1
[오픈소스컨설팅] Open stack kilo with DVR_CEPH_v1.1
 
Openstack live migration
Openstack live migrationOpenstack live migration
Openstack live migration
 
NodeJs로 디바이스 통신하기
NodeJs로 디바이스 통신하기NodeJs로 디바이스 통신하기
NodeJs로 디바이스 통신하기
 
KAFKA 3.1.0.pdf
KAFKA 3.1.0.pdfKAFKA 3.1.0.pdf
KAFKA 3.1.0.pdf
 
[드론] 펌웨어 분석 [2015.5.23]
[드론] 펌웨어 분석 [2015.5.23][드론] 펌웨어 분석 [2015.5.23]
[드론] 펌웨어 분석 [2015.5.23]
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JS
 
하이퍼레저 페이지 단위 블록 조회
하이퍼레저 페이지 단위 블록 조회하이퍼레저 페이지 단위 블록 조회
하이퍼레저 페이지 단위 블록 조회
 
[232] 수퍼컴퓨팅과 데이터 어낼리틱스
[232] 수퍼컴퓨팅과 데이터 어낼리틱스[232] 수퍼컴퓨팅과 데이터 어낼리틱스
[232] 수퍼컴퓨팅과 데이터 어낼리틱스
 
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
 
[오픈소스컨설팅] 스카우터 사용자 가이드 2020
[오픈소스컨설팅] 스카우터 사용자 가이드 2020[오픈소스컨설팅] 스카우터 사용자 가이드 2020
[오픈소스컨설팅] 스카우터 사용자 가이드 2020
 
[오픈소스컨설팅]Nginx jboss 연동가이드__v1
[오픈소스컨설팅]Nginx jboss 연동가이드__v1[오픈소스컨설팅]Nginx jboss 연동가이드__v1
[오픈소스컨설팅]Nginx jboss 연동가이드__v1
 
[225]빅데이터를 위한 분산 딥러닝 플랫폼 만들기
[225]빅데이터를 위한 분산 딥러닝 플랫폼 만들기[225]빅데이터를 위한 분산 딥러닝 플랫폼 만들기
[225]빅데이터를 위한 분산 딥러닝 플랫폼 만들기
 
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
 
Scala for play
Scala for playScala for play
Scala for play
 

Configuring global infrastructure in terraform

  • 1. 테라폼으로 글로벌 서비스 구성 - DRY 체험기 - devops@mykoon.com
  • 2. Spoon Radio Infra Member ● 노가다를 싫어하는 노땅 엔지니어 2명 ○ 최상기(Martin): https://www.linkedin.com/in/sanggi-choi/ ○ 백영진(Paul): https://www.linkedin.com/in/youngjin-baek-8a2a74a4/ ● 묵묵히 열심히 겁나게 달려주는 엔지니어 1명 ○ 박민호(Ash): https://www.linkedin.com/in/park-minho-4896b7117/
  • 3. Agenda ● Spoon Radio 소개 ● 요구 사항 ● 인프라 구성 도구 ● 코드 중복 극복기 (DRY Journey) ○ Phase 1: Terraform ○ Phase 2: Terraform Module ○ Phase 3: Terragrunt ○ 고민 ○ 숙제 ● 정리
  • 4. SPOON RADIO ● 개요: 개인 오디오 라이브 스트리밍 모바일 플랫폼 ● 특징: 10 ~ 20대를 타겟팅 한 모바일 미디어 채널 ● 2016년(한국), 2017년(인도네시아/베트남), 2018년(일본/중동 GCC 5개국) ● 글로벌 다운로드 900만 / 글로벌 MAU 170만
  • 5. 6개월 간의 중복 코드 탈출기(ing) ● WET: Write Everything Twice ○ 중복, 반복된 코드 ○ 수정 및 재 활용 하는데 많은 비용 발생 ● DRY: Don't Repeat Yourself ○ 품질과 무결성 확보 ○ 읽기 쉽고 ○ 재활용 가능 ○ 수정 및 활용 하는데 비용이 낮음.
  • 6. 요구 사항 ● 보통 인프라 구조는 거의 유사하지만, 아주 약간 다른 환경 구성 관리를 해야 함. ○ multiple aws accounts & region , environments, ○ aws resource(IAM, VPC, Subnet, RDS, EC2, Aurora, ALB, Lambda, S3, Route53 and so on.) => 5개국 서비스 구성시 15개의 유사 인프라 구성과 관리 ● 기존 Legacy Infra를 Code 기반으로 자동화 ○ AWS Well-Architected & ISMS & ISO27001 대응 인프라 구성 ○ 생산성이 높은 인프라 환경 구성
  • 7. 인프라 구성 도구 Code Repository Infrastructure Provisioning Image Management Configuration Management CI/CD Code Repository (Terraform, Packer, AWX, Ansible, Dockerfile..etc) AWS Infrastructure (VPC, Subnet, Security Group, IAM, S3.. etc) AWS AMI Base Image (Amazon Linux, Ubuntu, CentOS..etc) Software Provisioning (Nginx,Python,Java, Docker..etc) Continuous Integration & Delivery (Terraform, Packer, Application, Web) Terragrunt
  • 8. Phase 1 - Terraform ● IaC - 인프라 생성, 변경, 설정을 코드 관리 ○ 비용의 감소(돈, 인력, 노력 등) ○ 빠른 실행 속도 ○ 위험 관리 ○ 불확실성에 대한 유연함 - 아는 만큼 보이고, 처음 부터 완벽할 수 없다. ● Terraform ○ Terraform은 HashiCprop에서 만든 오픈 소스 도구이며, 인프라를 코드 형태로 정의하는 간편한 선언형 프로그래밍 언어 ■ Multi Provider ■ Large Community ○ 그냥 해 보고 싶었다.
  • 9. Phase 1 - 시작 ● VPC ● Subnet ● Route Table ● IGW ● NAT
  • 10. Phase 1 - 단순 리소스 나열 # kor/main.tf provider "aws" { region = "ap-northeast-2" access_key ="XXXXXXXXXXXXXXXX" secert_key ="XXXXXXXXXXXXXXXX" } resource "aws_vpc" "test-vpc" { cidr_block = "10.1.0.0/16" instance_tenancy = "default" enable_dns_support = "true" enable_dns_hostnames = "true" enable_classiclink = "false" tags { Name = "test-vpc" } } resource "aws_subnet" "public-subnet-2a" { vpc_id = "${aws_vpc.test-vpc.id}" cidr_block = "10.1.1.0/24" map_public_ip_on_launch = "true" availability_zone = "ap-northeast-2a" tags { Name = "public-subnet-2a" } } resource "aws_subnet" "private-subnet-2a" { vpc_id = "${aws_vpc.test-vpc.id}" cidr_block = "10.1.2.0/24" map_public_ip_on_launch = "false" availability_zone = "ap-northeast-2a" tags { Name = "private-subnet-2a" } } resource "aws_internet_gateway" "gw" { vpc_id = "${aws_vpc.test-vpc.id}" tags { Name = "internet-gateway" } } resource "aws_route_table" "rt1" { vpc_id = "${aws_vpc.test-vpc.id}" route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.gw.id}" } tags { Name = "Default" } } resource "aws_route_table_association" "association-subnet" { subnet_id = "${aws_subnet.public-1.id}" route_table_id = "${aws_route_table.rt1.id}" } output "vpc-id" { value = "${aws_vpc.test-vpc.id}" } output "vpc-public-subnet-cidr" { value = "${aws_subnet.public-subnet-2a.cidr_block}" } output "vpc-public-subnet-id" { value = "${aws_subnet.public-subnet-2a.id}" } output "vpc-private-subnet-cidr" { value = "${aws_subnet.private-subnet-2a.cidr_block}" } output "vpc-private-subnet-id" { value = "${aws_subnet.private-subnet-2a.id}" }
  • 11. Phase 1 - main.tf 중복 KR JP IN VE MENA + PRD - main.tf + STG - main.tf + DEV - main.tf + PRD - main.tf + STG - main.tf + DEV - main.tf + PRD - main.tf + STG - main.tf + DEV - main.tf + PRD - main.tf + STG - main.tf + DEV - main.tf + PRD - main.tf + STG - main.tf + DEV - main.tf ● 5개 국가, 3개의 인프라 환경 => 총 15개의 인프라 환경을 구성 관리해야 함. ○ 국가, 환경은 다르지만 동일한 인프라 구조를 만들기 위한 중복되는 옵션의 resource가 다수 발생. ○ 대략 100 ~ 200 line 수준의 main.tf WET Code 발생.
  • 12. Phase 1 - 결국 ● 단순 리소스 나열만으로는 15벌 인프라 전개 불가능 ○ 재활용이 불가능 ○ 비슷한 리소스의 대량 중복 발생 ○ 유지 보수 불가능 ○ 이렇게 할 거면 Hands - On과 차이가....
  • 13. Phase 2 - Terraform Module ● Data를 변수 처리한 리소스 구성 파일 묶음. ○ 비슷한 리소스를 반복 정의하는 고통에서 벗어날 수 있다. ○ 사용자 정의 모듈 만들어 활용 ○ 외부에서 이미 잘 만들어둔 모듈 활용 ■ https://registry.terraform.io/ ■ https://github.com/cloudposse ■ https://github.com/terraform-aws-modules ○ 리소스에는 versioning이 안되지만, 모듈에는 버저닝 가능 -> 모듈간 독립성 확보(의존성 제거)
  • 14. Phase 2 - 시도 # terraform-aws-vpc/main.tf locals { max_subnet_length = max( length(var.private_subnets), length(var.elasticache subnets), length(var.database_subnets), length(var.redshift_subnets), ) nat_gateway_count = var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length ………… 길어요... # prd-kr/main.tf terraform { backend "s3" { bucket = "backend-bucket" key = "prd-kr-vpc/terraform.tfstate" region = "ap-northeast-2" profile = "prd-kr" } } provider aws { region = "ap-northeast-2" profile = "prd" } module "network" { source = "../modules/network" name = "${var.name}" cidr = "${var.cidr}" azs = "${var.azs}" public_subnets = "${var.public_subnets}" env = "${var.env}" } # prd-kr/vars.tf variable name { type = "string" default = "" } variable cidr { type = "string" default = "0.0.0.0/0" } variable public_subnets { type = "list" default = ["0.0.0.0/0"] } variable private_subnets { type = "list" default = ["0.0.0.0/0"] } variable azs { type = "list" default = [""] } # prd-kr/terraform.tfvars name = "prd-kor-vpc" cidr = "10.1.0.0/16" public_subnets = ["10.1.1.0/24", ...] public_subnets = ["10.1.2.0/24", ...] asz = ["ap-northeast-2a", ...] env = "prd-kor
  • 15. vars.tf Duplicated main.tf Duplicated Phase 2 - Repeat Itself, Again ● module을 사용하면서 resource는 재활용이 가능해 졌지만, root module을 참조하는 sub module과 변수 정의 부분은 각 환경별 중복이 발생 ● terraform.tfvars을 제외한 곳에서 WET code 발생 # jpn/terraform.tfvars name = "prd-jpn-vpc" cidr = "10.2.0.0/16" public_subnets = ["10.2.0.0/24", ...] public_subnets = ["10.2.1.0/24", ...] asz = ["ap-northeast-2a", ...] env = "prd-kor # kor/terraform.tfvars name = "prd-kor-vpc" cidr = "10.1.0.0/16" public_subnets = ["10.1.1.0/24", ...] public_subnets = ["10.1.2.0/24", ...] asz = ["ap-northeast-2a", ...] env = "prd-kor # kor/main.tf module "network" { source = "../modules/network" name = "${var.name}" cidr = "${var.cidr}" azs = "${var.azs}" public_subnets = "${var.public_subnets}" env = "${var.env}" } # kor/vars.tf variable name { type = "string" default = "" } variable cidr { type = "string" default = "0.0.0.0/0" } # jpn/main.tf module "network" { source = "../modules/network" name = "${var.name}" cidr = "${var.cidr}" azs = "${var.azs}" public_subnets = "${var.public_subnets}" env = "${var.env}" } # jpn/vars.tf variable name { type = "string" default = "" } variable cidr { type = "string" default = "0.0.0.0/0" }
  • 16. Phase 2 - 세상에 공짜는 없다. ● multiple env에서 그래도 중복 발생(main.tf, var.tf) ○ 5개 국가, 3개 환경 구성에 대한 중복은 그대로 ○ global, local 변수 정의 관리 불편 ● 오픈소스 모듈도 결국 내 입맛에 맞게 수정 ○ 조금만 바꿔도 삭제 후 재 생성 ㅜㅜ ■ 요구 사항에 맞게 Lifecycle 관리 추가 ○ resource 생성을 모듈 하위에서 생성하기에 수정하기가 불가함 ○ 결국에 오픈소스 전체 코드 분석 후 수정함
  • 17. Phase 3 - Terragrunt ● gruntworks.io에서 개발하고, Terraform만으로는 부족한 기능 보완 ● 단순한 인프라는 Terraform으로도 충분하다. 그러나 인프라 구성이 커질 수록 모듈간의 연관 관계 및 중복 발생 ● Orchestration = Terragrunt ○ 모듈 간의 코드 중복을 최소화 ○ 모듈 간의 종속 관계 제거 Gruntwork.io
  • 18. Terragrunt 기본 구조 ● /terraform.tfvars ○ terragrunt의 환경설정 ● /globals.tfvars ○ root module ○ root vars ● locals.tfvars ○ sub module ○ sub vars ● terraform.tfvars ○ 각각의 vars terragrunt = { …. terraform { extra_arguments "-var-file" { commands = ["${get_terraform_commands_that_need_vars()}"] optional_var_files = [ "${get_tfvars_dir()}/${find_in_parent_folders("globals.tfvars", "ignore")}", "${get_tfvars_dir()}/${find_in_parent_folders("locals.tfvars", "ignore")}" ] } } } namespace = "prod" # dynamodb & s3 bucket = "prod-terraform-state" config_region = "ap-northeast-2" dynamodb_table = "prod-terraform-db" stage = "kor" aws_region = "ap-northeast-2" # remote state key vpc_remote_state_key = "prod/kor/terraform.tfstate" terragrunt = { terraform { source = "git::ssh/spooncast/terraform-service-repo.git?ref=release/v0.0.1//bastion" } include = { path = "${find_in_parent_folders()}" } } name = "bastion" instance_type = "t2.micro" cidr_office = "xxx.xxx.xxx.xxx/32"
  • 19. 코드와 데이터의 분리(Data Driven Design) # prod/main.tf terraform { # The configuration for this backend will be filled in by Terragrunt backend "s3" {} } provider aws { region = "${var.region}" profile = "${var.profile}" } module "network" { source = "terraform-aws-modules/vpc/aws" name = "${var.name}" cidr = "${var.cidr}" azs = "${var.azs}" public_subnets = "${var.public_subnets}" env = "${var.country}" } # global.tfvars profile = "prod" # prod/local.tfvars region = "ap-northeast-2" country = "kr" # prod/terraform.tfvars terragrunt = { terraform { source = "network" } include = { path = "${find_in_parent_folders()}" } } name = "vpc-prd-kor" cidr = "10.1.0.0/16" azs = ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c"] public_subnets = ["10.1.1.0/24", "10.1.2.0/24, "10.1.3.0/24] # prod/local.tfvars region = "ap-northeast-1" country = "jp" # prod/terraform.tfvars terragrunt = { terraform { source = "network" } include = { path = "${find_in_parent_folders()}" } } name = "vpc-prd-jp" cidr = "10.2.0.0/16" azs = ["ap-northeast-1a", "ap-northeast-1b", "ap-northeast-1c"] public_subnets = ["10.2.1.0/24", "10.2.2.0/24, "10.2.3.0/24] # prod/local.tfvars region = "ap-south-1" country = "mena" # prod/terraform.tfvars terragrunt = { terraform { source = "network" } include = { path = "${find_in_parent_folders()}" } } name = "vpc-prd-mena" cidr = "10.3.0.0/16" azs = ["ap-south-1a", "ap-south-1b", "ap-south-1c"] public_subnets = ["10.3.1.0/24", "10.3.2.0/24, "10.3.3.0/24]
  • 20. output 참조 #local.tfvars namespace = "prod" stage = "kor" aws_region = "ap-northeast-2" # remote state key vpc_remote_state_key = "prod/kor/xxx/terraform.tfstate" #data.tf data "terraform_remote_state" "vpc" { backend = "s3" config { bucket = "${var.bucket}" key = "${var.vpc_remote_state_key}" region = "${var.config_region}" encrypt = true dynamodb_table = "${var.dynamodb_table}" acl = "bucket-owner-full-control" } # https://www.terraform.io/docs/providers/consul/index.html backend = "consul" config { address = "${var.consul_address}" path = "${var.vpc_remote_state_key}" datacenter = "${var.datacenter}" } } # global.tfvars profile = "prod"
  • 21. Dependencies between modules terragrunt = { terraform { source = "../../../modules//services//was" } include = { path = "${find_in_parent_folders()}" } dependencies { paths = ["../network"] } } ... 주의 (主義) Terragrunt up-all 실행시 Dependencies까지 함께 생성됨. 하지만 all로 생성된 모듈을 destroy 을 할 경우 같이 생성 된 dependencies 까지 삭제 함.
  • 22. Terraform & Terragrunt Code Version terragrunt = { terraform { source = "git::ssh://git@github.com/tf-service-repo.git?ref=rel ease/v0.0.1//api" } include = { path = "${find_in_parent_folders()}" } ... module "api" { source = "git::ssh://git@github.com//tf-module-repo.git?ref=r elease/v0.0.1//ec2" instance_count = "${var.instance_count}" instance_type = "${var.instance_type}" associate_public_ip_address = "${var.associate_public_ip_address}" subnet_ids = ["${data.aws_subnet.subnet.*.id}"] ... Terraform Module Layer Service Layer Terragrunt Layer
  • 23. Terraform & Terragrunt Structure Terraform Module Repo Service Repo Terragrunt Repo
  • 24. 고민 ● Terraform 통한 인프라 구성이 빠르지 않다 ○ Terraform 코드 개발 및 검증 ○ Terraform Learning cove ○ 손으로 작업 했던 경험 ○ 이상과 현실 ● Terragrunt도 사용해야 한다. ○ Terraform Enterprise에는 Terragrunt에서 제공하는 대분분의 기능을 제공한다던데... 손은 (눈)코드보다 빠르다
  • 25. 숙제 ● Terraform 모듈 테스트 및 검증 ○ CI pipeline 통한 모듈 테스트 도입 ● PRD 환경 적용 후 리소스 삭제 방지 ○ Terraform Lifecycle 설정 ○ plan 통한 생성 및 삭제 리뷰 프로세스 수립 ● tfstate 파일 시각화 ○ tfstate 변경 이력 관리 (Terraboard 도입) ● Data Security (ssh key, password) ○ Vault, Consul 통한 데이터 보안
  • 26. 정리 ● “상용 수준 인프라를 구성하고 운영 하는 것은 매우 어렵다”것 인지 하자. ● (AWS) 기본 디자인을 잘 하자. ● DRY를 실천하기 위해 노력 하자. ○ 한 곳에 너무 많은 리소스를 정의 하지 말자. ○ 중복을 최소화하고, 최대한 작게 서로 독립적으로 단순하게 구성 하자. ● 팀에서의 강력한 의지가 없다면 하지 말자.. (아무리 좋아도 관리 안되면 허사) ● 불확성(외부 요구 사항)에 대한 보다 유연한 대응을 위해 노력해야 합니다.
  • 27. Spoon Radio Infra Member ● 노가다를 싫어하는 노땅 엔지니어 2명 ● 묵묵히 열심히 달려주는 엔지니어 1명 ● 그리고 함께 경험 하실 분 모십니다.
  • 28. Reference ● https://en.wikipedia.org/wiki/Don%27t_repeat_yourself ● https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/ ● https://blog.gruntwork.io/5-lessons-learned-from-writing-over-300-000-lines-of-infrastructure-code-36ba7fadeac1 ● https://www.slideshare.net/AntonBabenko/terraform-modules-and-some-of-bestpractices-march-2019 ● https://qiita.com/billthelizard/items/9e113f3f569db4f569a5 ● https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/2.7.0 ● https://caylent.com/devops-and-dry/ ● https://techblog.gumgum.com/articles/introducing-terraform-at-gumgum ● https://blog.gruntwork.io/ ● https://www.slideshare.net/AntonBabenko/terraform-modules-and-some-of-bestpractices-march-2019 ● https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/ ● https://www.44bits.io/ko/post/terraform_introduction_infrastrucute_as_code