T101-3주차(도전과제) [Terraform 101 Study]

cloudNet@ 팀의 가시다 님이 진행하는 테라폼 102 스터디 입니다. (테라폼으로 시작하는 IaC” (한빛미디어) 도서로 진행!)

  • 조건문을 활용하여 (각자 편리한) AWS 리소스를 배포하는 코드를 작성해보자
provider "aws" {
  region  = "ap-northeast-2"
}

# EC2 인스턴스 유형 변수 정의 (문자열, 기본값: 공백)
variable ec2_type {
  type        = string
  #"" 빈공백 그래야 조건 사용가능
  default     = ""
  
}

# 가장 최근의 Amazon Linux 2 AMI를 검색하는 데이터 소스 설정
data "aws_ami" "last_ami" {
  most_recent = true # 최근 생성된 AMI 사용

  # 내장 필터를 이용해 오너 별칭이 "amazon"인 것 필터
  filter {
    name   = "owner-alias"
    values = ["amazon"]
  }

  # 내장 필터를 이용해 이름 패턴이 "amzn2-ami-hvm-*-x86_64-ebs"인 것 필터
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-ebs"]
  }

  owners = ["amazon"] # 오너가 아마존인 AMI만 사용
}

# AWS 인스턴스 리소스 생성
resource "aws_instance" "test-server" {
  count = 1 # 생성할 인스턴스 수

  # data.aws_ami.last_ami에서 가져온 최신 AMI 사용
  ami           = data.aws_ami.last_ami.id

  # 인스턴스 타입 설정. var.ec2_type 변수에 값이 설정되어 있다면 해당 값을, 그렇지 않다면 기본값으로 "t2.nano" 사용.
  instance_type = var.ec2_type != "" ? var.ec2_type : "t2.nano"

  # 태그 설정: 이름은 "Server n" (n은 각 인스턴스의 숫자)
  tags = {
    Name = "test-server ${count.index}"
  }
}

  • 내장 함수을 활용하여 (각자 편리한) 리소스를 배포하는 코드를 작성해보자!
provider "aws" {
  region  = "ap-northeast-2"
}

variable ec2_type {
  type    = string
  default = ""
}

data "aws_ami" "last_ami" {
  most_recent = true

  filter {
    name   = "owner-alias"
    values = ["amazon"]
  }

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-ebs"]
  }

  owners = ["amazon"]
}

resource "aws_instance" "test-server" {
  count = 1

  ami           = data.aws_ami.last_ami.id
  instance_type = var.ec2_type != "" ? var.ec2_type : "t2.nano"

  tags = {
    # timestamp() 함수를 사용하여 현재 시간을 출력합니다. 
    Name = "test-server-${count.index}-${timestamp()}"
  }
}

  • AWS EC2 배포 시 remote-exec/file , terraform_data 활용하는 코드를 작성해보자
# AWS 프로바이더 설정 및 ap-northeast-2(서울) 리전 사용
provider "aws" {
  region = "ap-northeast-2"
}

# 보안 그룹 생성(t101sg라는 이름으로)
resource "aws_security_group" "instance" {
  name = "t101sg"

  # 인바운드 규칙 설정(one)
  # HTTP 접속을 위한 인바운드 규칙 (포트 80 개방)
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # 인바운드 규칙 설정(two)
  # SSH 접속을 위한 인바운드 규칙 (포트 22 개방)
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# AWS EC2 인스턴스 생성
resource "aws_instance" "example" {
  ami                    = "ami-0c9c942bd7bf113a2"       # 사용할 인스턴스 이미지 ID 설정
  instance_type          = "t2.micro"                   # 인스턴스 유형 설정
  subnet_id              = "subnet-07fa4fc702e8b566b"             # 사용할 서브넷 ID 설정
  private_ip             = "172.31.0.100"               # 인스턴스의 사설 IP 설정
  key_name               = "kp-sumin"                  # Key Pair 설정  , 각자 자신껄로 설정!
  vpc_security_group_ids = [aws_security_group.instance.id] # 생성한 보안 그룹 연결 설정

  # 사용자 정의 정보 실행
  # 시작 시 스크립트를 실행하여 문자열을 index.html 파일에 작성하고, HTTP 서버 구동
  user_data = <<-EOF
              #!/bin/bash
              echo "minho, T101 Study" > index.html
              nohup busybox httpd -f -p 80 &
              EOF

  # 인스턴스에 태그(Name = Single-WebSrv) 추가
  tags = {
    Name = "Single-WebSrv"
  }
}

# 고정 IP(Elastic IP) 생성 및 인스턴스에 연결
resource "aws_eip" "myeip" {
  instance = aws_instance.example.id       # 인스턴스 연결 설정 / aws_instance라는 Terraform 리소스를 생성하면, 해당 인스턴스의 ID는 .id를 통해 도출할 수 있습니다.
  associate_with_private_ip = "172.31.0.100"        # 사설 IP와 연관 설정
}

# 생성된 인스턴스의 고정 IP 출력
resource "null_resource" "echomyeip" {
  provisioner "remote-exec" {
		#연결
    connection {
			#고정 퍼블릭 ip로 연결
      host = aws_eip.myeip.public_ip
      type = "ssh"
      user = "ubuntu"
      private_key =  file("/Users/minho/.ssh/kp-minho.pem")    # 사설 키에 대한 경로 설정  , 각자 자신들의 경로 
			#password = "qwe123"  만약 패스워드로 로그인할시 
    }
		#원격 서버에서 실행할 명령을 정의
    inline = [
			#EIP(Elastic IP)의 public IP 주소를 출력하는 작업을 수행
      "echo ${aws_eip.myeip.public_ip}"
      ]
  }
}

# 인스턴스의 공인 IP 출력
output "public_ip" {
  value       = aws_instance.example.public_ip
  description = "The public IP of the Instance"
}

# 인스턴스의 고정 IP 출력
output "eip" {
  value       = aws_eip.myeip.public_ip
  description = "The EIP of the Instance"
}

  • moved 블록을 사용한 테라폼 코드 리팩터링을 수행해보세요
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "minho" {
  ami                    = "ami-00d253f3826c44195"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = <<-EOF
              #!/bin/bash
              yum install -y httpd
              systemctl start httpd
              echo "Hello, T101 Study" > /var/www/html/index.html
              EOF

  tags = {
    Name = "Single-WebSrv"
  }
}

resource "aws_security_group" "instance" {
  name = var.security_group_name

  ingress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
  }

  egress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
  }
}

variable "security_group_name" {
  description = "The name of the security group"
  type        = string
  default     = "terraform-example-instance"
}

그후 EC2 의 resource 이름 minho ⇒ minho5로 변경 합니다

provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "minho5" {
  ami                    = "ami-00d253f3826c44195"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = <<-EOF
              #!/bin/bash
              yum install -y httpd
              systemctl start httpd
              echo "Hello, T101 Study" > /var/www/html/index.html
              EOF

  tags = {
    Name = "Single-WebSrv"
  }
}

resource "aws_security_group" "instance" {
  name = var.security_group_name

  ingress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
  }

  egress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
  }
}

variable "security_group_name" {
  description = "The name of the security group"
  type        = string
  default     = "terraform-example-instance"
}


  moved {
    from = aws_instance.minho
    to   = aws_instance.minho5
  }
# terraform plan
aws_security_group.instance: Refreshing state... [id=sg-0ee5f8e7b8c714c69]
aws_instance.minho5: Refreshing state... [id=i-0da9a1bb0ff210afd]

Terraform will perform the following actions:

  # aws_instance.minho has moved to aws_instance.minho5
    resource "aws_instance" "minho5" {
        id                                   = "i-0da9a1bb0ff210afd"
        tags                                 = {
            "Name" = "Single-WebSrv"
        }
        # (32 unchanged attributes hidden)

        # (8 unchanged blocks hidden)
    }

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

------
/3.3$ terraform state list
aws_instance.minho5
aws_security_group.instance

완료 후 move 부분을 주석 하면 리팩터링까지 완료가 됩니다.

  • AWS의 S3 버킷을 2개의 리전에서 동작하는 테라폼 코드를 작성해보세요!
- provider block을 2개 생성하고, alias를 각각 seoul_region와 Singapore_region으로 설정합니다.
- s3를 생성하기 위한 aws_s3_bucket에 각각 provider를 원하는 리전의 alias로 지정합니다.
============================================================================================================
provider "aws" {
  region = "ap-northeast-2"
  alias  = "seoul_region"
}

provider "aws" {
  region = "ap-southeast-1"
  alias  = "Singapore_region"
}

variable "name" {
  default = "treemin-te1st-s3"
}

resource "aws_s3_bucket" "seoul_bucket" {
  bucket = "${var.name}-seoul"
  provider = aws.seoul_region

}

resource "aws_s3_bucket" "Singapore_bucket" {
  bucket = "${var.name}-singapore"
  provider = aws.Singapore_region

}
위로 스크롤