본문 바로가기

♻ Terraform(테라폼)/Terraform 활용

테라폼을 활용한 단일서버 배포

요약 

더보기

terraform 초기 플랫폼 적용 명령어 : terraform init

tarraform 코드 작성 후 생성할 리소스 확인 : terraform plan

terraform 리소스 적용 : terraform apply

terraform 전체 코드

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

resource "aws_instacne" "example" {
	ami	= "ami-0454bb2fefc7de534"
	instance_type = "t2.micro"
}

 

테라폼을 사용하는 첫 번째 단계는 공급자를 구성하는 것인데, 빈 폴더를 만들고 main.tf 라는 파일에 다음과 같은 내용을 작성하고 저장 한다.

terraform을 설치하는 과정은 아래를 참조 한다.

2021.12.27 - [Terraform(테라폼)] - Windows 환경에서 Terraform 설치하기

 

Windows 환경에서 Terraform 설치하기

# Windows 환경에서 Terraform을 설치하는 방법에 대해서 알아 보겠습니다. 1. 해당 url에 접근하여 테라폼을 다운로드 합니다. https://www.terraform.io/downloads Downloads | Terraform by HashiCorp Terrafor..

may9noy.tistory.com

terraform 설치 후 CMD 에서 확인하는 방법

CMD 화면에서 terraform을 입력하면 아래와 같이 안내 명령어들이 나온다. 아래와 같이 나오면 설치가 정상적으로 되었으며, 사용이 가능하다고 보면 된다.

C:\Users\hist\terraform>terraform
Usage: terraform [global options] <subcommand> [args]

The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.

Main commands:
  init          Prepare your working directory for other commands
  validate      Check whether the configuration is valid
  plan          Show changes required by the current configuration
  apply         Create or update infrastructure
  destroy       Destroy previously-created infrastructure

All other commands:
  console       Try Terraform expressions at an interactive command prompt
  fmt           Reformat your configuration in the standard style
  force-unlock  Release a stuck lock on the current workspace
  get           Install or upgrade remote Terraform modules
  graph         Generate a Graphviz graph of the steps in an operation
  import        Associate existing infrastructure with a Terraform resource
  login         Obtain and save credentials for a remote host
  logout        Remove locally-stored credentials for a remote host
  output        Show output values from your root module
  providers     Show the providers required for this configuration
  refresh       Update the state to match remote systems
  show          Show the current state or a saved plan
  state         Advanced state management
  taint         Mark a resource instance as not fully functional
  test          Experimental support for module integration testing
  untaint       Remove the 'tainted' state from a resource instance
  version       Show the current Terraform version
  workspace     Workspace management

Global options (use these before the subcommand, if any):
  -chdir=DIR    Switch to a different working directory before executing the
                given subcommand.
  -help         Show this help output, or the help for a specified subcommand.
  -version      An alias for the "version" subcommand.

테라폼을 활용한 AWS 단일 인스턴스 배포

문법은 매우 간단하다.

리눅스에서 vi 에디터를 사용하는 것처럼, Windows에서 vi 처럼 텍스트 에디터를 사용 할 수 있다.

CMD 화면에서 notepad main.tf 라고 입력하면 해당 폴더에 main.tf 파일이 생성 된다.

2022-04-13  오전 10:16    <DIR>          .
2022-04-13  오전 10:16    <DIR>          ..
2022-04-13  오전 10:04    <DIR>          .terraform
2022-04-13  오전 10:04             1,151 .terraform.lock.hcl
2022-04-13  오전 10:08               150 main.tf
2022-04-13  오전 10:16                20 test_01.t

최초에 terraform init 이라는 명령어를 통해, 최초 실행을 해야한다.

terraform init을 하는 이유는 멀티 플랫폼을 지원하는 terraform은 init을 통해 해당 플랫폼이 어떤것인지 확인하는 작업을 해야한다.

terraform init을 수행하면 아래와 같은 화면이 표시된다.

C:\Users\hist\terraform>terraform init

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v4.9.0...
- Installed hashicorp/aws v4.9.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

생성된 main.tf 파일에서 서울 리전인 ap-northeast-2를 선택하고, example이라는 t2.micro 인스턴스를 생성하는 코드를 테라폼으로 작성한다.

여기서 각각 리전과 resource를 명명해 주면 되는데 리소스에는 aws instance를 생성하겠다는 "aws_instance"  와 해당 instance의 이름을 각각 "example"이라고 명명한다. 그리고 해당 인스턴스의 스펙은 ami 와 instance_type을 통해서 지정 할 수 있다.

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

resource "aws_instacne" "example" {
	ami	= "ami-0454bb2fefc7de534"
	instance_type = "t2.micro"
}

위와 같은 코드를 작성하고, terraform은 해당 코드가 실행 됐을때 어떤 자원이 생성되는지 확인할 수 있는 terraform plan이라는 명령어를 제공하고 있다.

terraform plan을 실행하면 아래와 같이 어떤 자원들이 생성될 것이지 파악이 가능하다.

C:\Users\hist\terraform>terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                                  = "ami-0c55b159cbfafe1f0"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t2.micro"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = (known after apply)
      + monitoring                           = (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + subnet_id                            = (known after apply)
      + tags_all                             = (known after apply)
      + tenancy                              = (known after apply)
      + user_data                            = (known after apply)
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = (known after apply)

      + capacity_reservation_specification {
          + capacity_reservation_preference = (known after apply)

          + capacity_reservation_target {
              + capacity_reservation_id = (known after apply)
            }
        }

      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + tags                  = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }

      + enclave_options {
          + enabled = (known after apply)
        }

      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }

      + metadata_options {
          + http_endpoint               = (known after apply)
          + http_put_response_hop_limit = (known after apply)
          + http_tokens                 = (known after apply)
          + instance_metadata_tags      = (known after apply)
        }

      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)
        }

      + root_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + tags                  = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }
    }

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

plan 명령을 통해서 테라폼이 main.tf 파일을 통해서 생성할 자원에 대해서 확인 할 수 있었다. 이것은 실제 운영환경에 배포 하기전에 코드의 온전성과 해당 리소스의 변경사항을 사전에 확인할 수 있는 좋은 도구이다.

위에서 더하기(+) 표기가 있는것은 리소스의 추가를 뜻하고, 빼기(-) 표기가 있는것은 해당 자원의 삭제, 물결표(~)가 있는것은 해당 자원의 수정을 나타 낸다.

위의 plan 코드에서 확인할 수 있는것은 테라폼이 단일 EC2 인스턴스만 생성한다는 것을 알 수 있다.

plan 작업을 완료 후 실제 AWS 인프라에 적용하는 명령어는 terraform apply 이다.

terraform apply를 적용한다는 것은 해당 폴더에 .tf 파일을 AWS 및 기타 클라우드 환경에 실제로 적용한다는 의미 이다.

terraform apply를 적용하여 신규 인스턴스를 생성해보자. 실행을 하고 아래와 같이 yes를 입력하면 실제 리소스가 생성된다.

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value:

terraform apply의 결과, 정상적으로 생성이 되었다고 나온다.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Still creating... [20s elapsed]
aws_instance.example: Still creating... [30s elapsed]
aws_instance.example: Creation complete after 31s [id=i-02ed6a76f1c24edf1]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

그렇다면 실제 AWS 콘솔 화면에서 정상적으로 EC2 인스턴스가 정상적으로 생성이 되었는지 확인한다.

인스턴스는 정상적으로 생성이 되었는데, 실제 리소스 정보를 확인해보면 모든 정보그 default 정보로 입력이 된것도 확인할 수 있었다.

이는 추후에 새로운 리소스를 추가로 적용할 수 있으므로, 디폴드 값을 유지한다.

그렇다면 여기서 해당 인스턴스를 식별 할 수 있는 태그를 적용해 본다.

위의 main.tf 파일안에 인스턴스를 생성하는 resource 내용안에 아래의 태그를 추가해 주면 된다.

tags = {
	Name = "terraform-example"
	}

추가 후 terraform plan을 적용해 보자.

aws_instance.example: Refreshing state... [id=i-02ed6a76f1c24edf1]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # aws_instance.example has changed
  ~ resource "aws_instance" "example" {
        id                                   = "i-02ed6a76f1c24edf1"
      + tags                                 = {}
        # (29 unchanged attributes hidden)





        # (5 unchanged blocks hidden)
    }


Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include
actions to undo or respond to these changes.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_instance.example will be updated in-place
  ~ resource "aws_instance" "example" {
        id                                   = "i-02ed6a76f1c24edf1"
      ~ tags                                 = {
          + "Name" = "terraform-example"
        }
      ~ tags_all                             = {
          + "Name" = "terraform-example"
        }
        # (28 unchanged attributes hidden)





        # (5 unchanged blocks hidden)
    }

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

위의 내용과 같이 tags 내용이 추가되어 적용이 될것이다 라는 내용이 표시된다.

terraform apply를 통해 적용을 한다.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.example: Modifying... [id=i-02ed6a76f1c24edf1]
aws_instance.example: Modifications complete after 0s [id=i-02ed6a76f1c24edf1]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

위의 내용을 보면 1개의 옵션이 변경 되었다고 나오며, 실제 AWS EC2 인스턴스를 확인하면 아래와 같이 태그가 추가된것을 확인 할수 있다.

그리고 태그가 추가된것과 동시에 instance 이름도 태그 이름으로 변경된것을 확인 할 수 있다.

테라폼 코드가 동작하면 버전 관리 도구에 저장하는것을 보통 권장한다. 왜냐하면 버전 관리 도구를 사용하면 다른 팀 구성원과 코드를 공유 할 수 있고, 모든 인프라의 변경 내용을 추적하거나 커밋 로그를 사용하여 디버깅도 가능하다.

해당 코드를 git을 통해 팀원들과 공유하려면 git 저장소를 구성해 주면 된다.