terraform
terraform 서비스 구축
Intro
- 본 문서는 terraform 으로 실습한 소스코드를 설명하는 데 중점을 두었습니다. 
- 본 문서는 markdown 언어로 제작 되었습니다. 
- 김태형(kimutae@naver.com) 의 저작물이며 무단 배포 / 재배포를 금합니다. 
IAC(infra as code) 이란
- 인프라를 코드로 프로비저닝 / 관리한다는 의미입니다. 
- 장점 
- 비용 절감 
- 배포 속도 향상 
- 오류 감소 
- 인프라 일관성 향상 
- 구성 변동 제거 
terraform 이란
- 테라폼(Terraform)은 하시코프(Hashicorp)에서 오픈소스로 개발중인 클라우드 인프라스트럭처 입니다. 
- 대표적인 public cloud 인 aws / gcp / azure 등을 모두 지원합니다. 
- 하시코프 설정 언어HCL(Hashicorp Configuration Language)을 사용해 클라우드 리소스를 선언합니다 
- 파일 확장자는 .tf입니다. 
terraform 명령어
- init : . terrform 초기화 이후 각 vendor사에 맞는 provier 파일을 설치 합니다. 
- plan : - 테라폼 프로젝트 디렉터리 아래의 모든 .tf 파일의 내용을 실제로 적용 가능한지 확인하는 작업을 계획 
- 테라폼은 이를 terraform plan 명령어로 제공하며, 이 명령어를 실행하면 어떤 리소스가 생성되고, 수정되고, 삭제 
 
- apply : - 테라폼 프로젝트 디렉터리 아래의 모든 .tf 파일의 내용대로 리소스를 생성, 수정, 삭제 
- 테라폼은 이를 terraform apply 명령어로 제공합니다. 이 명령어를 실행하기 전에 변경 예정 사항은 plan 명령어 
 
terraform 으로 구성하기 앞서 생각해야 할 점
- 상시 변경 인프라 / 기반인프라 구분 
- 테라폼을 사용하게 되면 한 디렉토리 내에 있는 모든 tf 파일들을 동시에 실행을 합니다. 
- 그렇기에 한번 구축하면 거의 변경 할 일이 없는 인프라와 상시로 변경이나 구축이 자주 일어나는 인프라를 구분해야 합니다. 
- 초기 구성 이후 거의 변하지 않는 항목은 vpc등 네트워크 인프라이며 - resource(신규생성)를 지정 해서 인프라를 생성 합니다. 
- 서비스 구성 시 항상 자주 구성해야 하는 항목 - data(불러오기) / resource를 혼용 하여 사용 합니다. 
- EX resourcedata- vpc - security gruop - subnet - Load Balancer - igw - target group - NAT - EC2 - ECS-Cluster - ecs - task difinition - ecr - RDS 
- code 재 사용이 가능하도록 설계 
- IAC 를 사용 한다는 것은 결국 인프라를 프로그래밍한다는 의미이며 프로그래밍 언어의 특징도 그대로 가져옵니다. 
- 한번 작성한 코드는 재 사용이 가능 하도록 설계 되어야 합니다. 
- 공통으로 사용하는 부분은 변수로 처리 해야 합니다. 
- 자주 사용 하는 구문은 모듈화 해야 합니다. 
variables를 활용한 code 사용 예시
- 변수지정 
variable "cidr_numeral" {
description = "The VPC CIDR numeral (10.x.0.0/16)"
type  = number
default = "30"
}
variable "cidr_numeral_public" {
default = {
    "0" = "0"
    "1" = "16"
    "2" = "32"
}
}
############# 가용 영역 지정 - 가용영역의 갯수만큼 서브넷이 만들어진다
variable "availability_zones" {
    type    = list(string)
    default = [
    "ap-northeast-2a" ,
    "ap-northeast-2b"
    ]
}- 사용 
    resource "aws_subnet" "public" {
    count  = length(var.availability_zones)  # 변수로 지정된 가용 영역의 갯수 현재 2 즉 변수는 0,1 
    vpc_id = aws_vpc.vpc.id #위에서 생성한 vpc 별칭 입력
    #################
    # count.index = for 문 역할 0 = 0 / 1=16
    cidr_block  = "10.${var.cidr_numeral}.${var.cidr_numeral_public[count.index]}.0/20"    
    # resource참조는 element 구문을 활용 하여 for 문을 작성합니다
    availability_zone = element(var.availability_zones, count.index)
    
    #################
    map_public_ip_on_launch = true
    tags = {
        Name = "public${count.index}-${var.vpc_name}"
    }
    }
    
디렉토리 구성
main
├── global           >> global 설정 - vpc를 추가 할때 사용
│   └── mk-network-var   >>  vpc / subnet /igw 등 네트워크 설정
│       ├── main.tf
│       ├── network.tf
│       ├── terraform.tfstate
│       ├── terraform.tfstate.backup
│       └── variables.tf
└── service
└── ecs-web
├── falgate   >> ecs-cluster 내 다중 서비스를 포함하고 있어 별도로 생성 할수 있도록 구성
│   ├── ecr.tf
│   ├── ecs-cluster.tf
│   ├── td-service
│   │   ├── ecs.tf
│   │   ├── serevice.conf.json
│   │   ├── serevice.conf.json.tpl
│   │   ├── td.tf
│   │   ├── terraform.tfstate
│   │   ├── terraform.tfstate.backup
│   │   └── variables.tf -> ../../variables.tf   >> 공용 변수를 사용 하기 위해 심볼릭 링크로 구성
│   ├── terraform.tfstate
│   ├── terraform.tfstate.backup
│   └── variables.tf -> ../variables.tf
├── sg-lb     >> security group 과 로드벨런서를 구성
│   ├── lb.tf
│   ├── output.tf
│   ├── sg.tf -> ../sg.tf
│   ├── terraform.tfstate
│   ├── terraform.tfstate.backup
│   ├── variables.tf -> ../variables.tf
├── sg.tf
└── variables.tf
VPC 구성

Load Balancer 구성
- 결과  
task definition 구성
- 결과  
ECS - service 구성
- 결과 

두 신뢰관계 정책 파일을 병합하는 jq 명령어
TrustShip
aws iam update-assume-role-policy --role-name MyRole --policy-document "$(
  aws iam get-role --role-name MyRole --query "Role.AssumeRolePolicyDocument" --output json | \
  jq -c '.Statement |= map(
    if .Principal.AWS then
      .Principal.AWS |= (if type == "string" then [.] else . end + ["arn:aws:iam::xxxx:root"] | unique)
    else
      .
    end
  )'
)"Last updated