클라우드 엔지니어/클라우드 캠프과정

Terraform (제어문 , 조건문)

해아's 2022. 11. 2. 16:55

Terraform 제어문

1) 반복문

(0) Set와 Map형 변수

set : 유일한 값의 요소들로 이루어진 list
	ex) [1, 2, 3]

map : Key-Value 형식의 데이터, key 값은 string이여야함

같은 라인의 값은 동일한 형식어야함. ex) { k : v, k2 : v2 }

(1) count를 이용한 방식

resource "aws_instance" "app_server" { #리소스
  count = 2 #카운트 속성 반복갯수
  ami           = var.app_server_ami #이미지명 > 변수로 만듬
  instance_type = var.app_server_in_type
  vpc_security_group_ids = ["sg-02567aade589e3c60"] #resource "aws_security_group" "ec2_allow_rule" 를 가져와서 설정해준다
  key_name = "ec01"
  tags = {
    Name = "web${count.index}"
  }
}
output "app_server_public_ip" { #출력
  description = "AWS_Public_Ip"
  value = aws_instance.app_server[*].public_ip # list 형식은 * 로 모두불러올수있다.
}

(2) foreach

- 변수의 값을 가져와서 반복하게 하고 속성에 for_each 를 추가하면된다
variable "server_names" {
  type        = list(any)
  description = "create EC2 server with three names"
  default     = ["web01", "web02"]
}

resource "aws_instance" "app_server" { #리소스
  ami           = var.app_server_ami #이미지명 > 변수로 만듬
  instance_type = var.app_server_in_type
  vpc_security_group_ids = ["sg-02567aade589e3c60"]
  key_name = "ec01"
  for_each = toset(var.server_names) # 선언한 server_names 를 가져와서 값만큼 반복
  tags = {
    Name = "${each.value}"
  }
}

output "app_server_public_ip" { #출력
  description = "AWS_Public_Ip"
  value = [ for server in aws_instance.app_server : server.public_ip ] #for_each 방식은 리턴이 키벨류 형식이라 * 로 불러올수가 없다.
}

실습 3개의 보안그룹 생성

  • sg_list 에 ssh : 20 , web :80 , was : 8009 여는 보안그룹 각각 생성
variable "sg_list" {
type        = map
default     = {"ssh_sg":22, "web_sg":80,"was_sg":8009}
/*
each.key , each.value 키벨류형식으로 출력
*/
}
resource "aws_security_group" "default_sg_add" {
for_each = var.sg_list
ingress {
    description = each.key
    from_port   = each.value
    to_port     = each.value
    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"]
}
tags = {
    Name = "${each.key}"
}
}
output "default_sg_add_description" { #출력
description = "default_sg_add_description"
value = [ for sg_name in aws_security_group.default_sg_add : sg_name.ingress.*.description  ]
}
output "default_sg_add_to_port" { #출력
description = "default_sg_add_to_port"
value = [ for sg_name in aws_security_group.default_sg_add : sg_name.ingress.*.to_port  ]
}
  • 실습2 하나의 보안그룹에 여러개의 포트를 지정하라
  • 실습 3
  1. VPC생성 : a,c 가용영역에 각 서브넷을 생성
  2. ssh_sg : 0.0.0.0/0 에 대해 22번 포트 허용
  3. web_sg : 0.0.0.0/0 에 대해 80,443번 포트 허용
  4. was_sg : a,c가용영역에 대해 8080.8009
  5. EC2생성 :
    • web(ec2) : ssh_sg , web_sg
    • was(ec2) : ssh_sg , was_sg

2) 조건문

  • 조건문
  • [1] count를 이용한 방법
variable "create_ec2" {
    type= bool
    default = true
}
resource "aws_instance" "app_server" {
    count = var.create_ec2 ? 1 : 0
    ami           = "ami-068a0feb96796b48d"
    instance_type = "t2.micro"
    key_name = "cloudkey"
    tags = {
        Name = "server"
    }
}
  • [2] 삼항연산자를 이용한 방법
variable "create_ec2" {
    type=bool
    default = true
}
resource "aws_instance" "app_server" {
    count = var.create_ec2 ? 1 : 0 #삼항연산자 조건이 ? 참 : 거짓
    ami= ami-068a0feb96796b48d"
    instance_type = "t2.micro"
    key_name = "ec01"
    associate_public_ip_address = true #공용아이피주소
    tags = {
        Name = "server"
    }
}
  • 조건을 걸때 오토스케일링이나 로드벨런서 사용여부 이런부분에 사용한다.
  • 실습 EC2를 생성할떄 변수로 ami 가 ubuntu로 입력하면 ami-068a0feb96796b48d
  • ami를 amazon을 입력하면 ami-09cf633fe86e51bf0가 실행되게 하라.
variable "ami" {
    type=string
    default = "ubuntu"
} 
ami= var.ami == "ubuntu" ? "ami-068a0feb96796b48d" : var.ami == "amazon" ? "ami-09cf633fe86e51bf0" : "ami-012b9d1d0d2e2c900"
#var.ami 가 우분투면 우분투설치 amazon이면 아마존 설치 그것도 아니면 윈도우 설치

실습

  1. VPC생성 : a,c 가용영역에 각 서브넷을 생성
  2. ssh_sg : 0.0.0.0/0 에 대해 22번 포트 허용
  3. web_sg : 0.0.0.0/0 에 대해 80,443번 포트 허용
  4. was_sg : a,c가용영역에 대해 8080.8009
  5. EC2생성 :
    • web(ec2) : ssh_sg , web_sg
    • was(ec2) : ssh_sg , was_sg

풀이

1. VPC 및 서브넷 생성 cdir_block = each.value

  • 변수선언
variable "my-vpc-subnet" {
type        = map
default     = {
    "a" : "200.200.10.0/24"
    "c" : "200.200.30.0/24"
}
  • 서브넷 설정
  resource "aws_subnet" "my-subnet" {
     for_each = var.my-vpc-subnet
     vpc_id     = aws_vpc.my-vpc.id
     cidr_block = each.value
     availability_zone = "ap-northeast-2${each.key}"
     map_public_ip_on_launch = true
     tags = {
        Name = "my-subnet-${each.key}"
     }
  }
  output "my-subnet-ids" {
     value = [for my-subnet in aws_subnet.my-subnet: my-subnet.id]
  }
  • 키포인트 정리
  • for_each = var.my-vpc-subnet #변수를 반복시켜 변수의 배열만큼 서브넷생성
  • Name = "my-subnet-${each.key}" #변수의 이름을 지정
  • cdir_block = each.value
  • availability_zone = "ap-northeast-2${each.key}"

2. 보안그룹

  • 변수선언
  variable "sg_list" {
     type = map
     default = {
        "ssh_sg" : {"22" : ["0.0.0.0/0"]},
        "web_sg" : {"80" : ["0.0.0.0/0"],"443" : ["0.0.0.0/0"]},
        "was_sg" : {"8080" : ["200.200.10.0/24", "200.200.30.0/24"],"8009" : ["200.200.10.0/24", "200.200.30.0/24"]},
     }
  }
  • 보안그룹 설정
  resource "aws_security_group" "default_sg_add" {
     vpc_id = aws_vpc.my-vpc.id
     for_each = var.sg_list
     dynamic ingress {
        for_each = each.value
        content {
           description = each.key
           from_port   = ingress.key
           to_port     = ingress.key
           protocol    = "tcp"
           cidr_blocks = ingress.value
        }
     }
     egress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = ["0.0.0.0/0"]
     }
     tags = {
        Name = "${each.key}"
     }
  }
  • 키포인트정리
  • 이중반복문 처리 for_each dynamic for_each
  • 변수의 map 구조 잘보기

3. EC2생성 :

  • web(ec2) : ssh_sg , web_sg #추후 반복문을 배우면 적용 지금은 모든 보안그룹 설정
  • was(ec2) : ssh_sg , was_sg #추후 반복문을 배우면 적용 지금은 모든 보안그룹 설정
  • 변수선언
  variable "app_list" {
     type = list
     default = [ "web","was" ]
  }
  • EC2생성
resource "aws_instance" "app_server" {
  for_each = toset(var.app_list)
  ami           = var.app_server_ami
  instance_type = var.app_server_in_type
  key_name = "ec01"
  subnet_id = each.value == "web" ? aws_subnet.my-subnet["a"].id :  aws_subnet.my-subnet["c"].id 
  #서브넷아이디 web서버면 서브넷a was서버면 서브넷c 에 셋팅
  associate_public_ip_address = true #공용아이피주소
  vpc_security_group_ids = each.value == "web" ? [ aws_security_group.default_sg_add["ssh_sg"].id, aws_security_group.default_sg_add["web_sg"].id] : [ aws_security_group.default_sg_add["ssh_sg"].id, aws_security_group.default_sg_add["was_sg"].id] 
  tags = {
    Name = "${each.value}"
  }
}
  output "app_server_public_ip" { #출력
     description = "AWS_Public_Ip"
     value = [for ec2 in aws_instance.app_server : ec2.public_ip ]
  }
  • 키포인트정리
  • for_each = toset(var.app_list) 리스트형식이라 toset으로 긁어옴

각 업무별로 분리하는게 좋다

  • vpc.tf # VPC관련된 부분만 모아둠
  • vpc_variables.tf # VPC 변수만 모아둠
  • sg.tf # 보안그룹 관련된 부분만 모아둠
  • sg_variables.tf # 보안그룹에서 사용하는 변수만 모아둠
  • main.tf
  • variables.tf
  • ※ terraform이 알아서 실행될수 있도록 왠만한 값들은 모두 변수에서 참조해서 작성해야 꼬이지 않는다

EC2생성 보안그룹 설정 바꾸기.

  • 기존 모든 보안그룹 다가져오기
  • vpc_security_group_ids = [ for sg in aws_security_group.default_sg_add: sg.id ]
  • 변경
  • vpc_security_group_ids = each.value == "web" ? [ aws_security_group.default_sg_add["ssh_sg"].id, aws_security_group.default_sg_add["web_sg"].id] : each.value == "was" ? [ aws_security_group.default_sg_add["ssh_sg"].id, aws_security_group.default_sg_add["was_sg"].id] : [aws_security_group.default_sg_add["ssh_sg"].id]

 

 

728x90
반응형