✅ 이 블로깅은 테라폼으로 시작하는 IaC 책을 기반으로 작성한다.


테라폼으로 AWS에서 EC2에 웹 서버를 배포할 것인데 조건은 아래와 같다

  • Ubuntu 에 apache(httpd)를 설치
  • index.html 생성(닉네임 출력)하는 user_data를 작성해서 설정 배포
  • 포트는 TCP 80 후 curl 접속

AWS를 프로바이더로 지정하고 배포하기 위해서는 awscli가 필요하다.

예전에 설치하고 configure 설정을 해 두어 이 과정은 생략한다

테라폼이 AWS에 접근하기 위해 awscli 설치와 Access key를 등록해야 하는 점을 잊지 말길 바란다!

  1. main.tf 파일을 작성한다.

    하나씩 뜯어 보겠다

    • aws에서 region 설정을 해 준다.

        provider "aws" {
          region = "ap-northeast-2"
        }
      
    • 인스턴스 설정을 해 준다.

      ami, 인스턴스 타입, 생성할 security group id, user data에 설치 또는 초기 설정에 필요한 코드 작성, 그리고 tags까지 지정해 주었다

        resource "aws_instance" "example" {
          ami                    = "ami-0c9c942bd7bf113a2"
          instance_type          = "t2.micro"
          vpc_security_group_ids = [aws_security_group.instance.id]
              
          user_data = <<-EOF
                      #!/bin/bash
                      echo "Hello, gain" > index.html
                      nohup busybox httpd -f -p 80 &
                      EOF
              
          tags = {
            Name = "Single-WebSrv"
          }
        }
      
    • security group 설정을 하는데 80으로 노출시킬거라 포트 tcp 80을 지정해 주었고 variable로 따로 빼서 sg명을 설정하였다

        resource "aws_security_group" "instance" {
          name = var.security_group_name
              
          ingress {
            from_port   = 80
            to_port     = 80
            protocol    = "tcp"
            cidr_blocks = ["0.0.0.0/0"]
          }
        }
              
        variable "security_group_name" {
          description = "The name of the security group"
          type        = string
          default     = "terraform-example-instance"
        }
      
    • output은 public ip을 해 주어 해당 ip로 접속해 볼 것이다

        output "public_ip" {
          value       = aws_instance.example.public_ip
          description = "The public IP of the Instance"
        }
      
  2. terraform init을 수행한다.

     $ terraform init
        
     	Initializing the backend...
        	
     	Initializing provider plugins...
     	- Finding latest version of hashicorp/aws...
     	- Installing hashicorp/aws v5.15.0...
     	- Installed hashicorp/aws v5.15.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에 지정한 aws 프로바이더 버전이 설치 된다

    테라폼은 친절하다.

    .terraform.lock.hcl에 프로바이더 버전을 기록해 둔다는 말과

    terraform plan을 수행하라는 말과

    module이나 backend 설정이 바꼈을 때 init을 다시 수행하라는 말을

    아주 친절하게 해 영어로 말해 준다 ㅎㅅㅎ

  3. terraform plan으로 내가 짠 코드 계획을 수행해 본다

     $ 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" {
     	     ...중략...
     	      + tags                                 = {
     	          + "Name" = "Single-WebSrv"
     	        }
     	      + tags_all                             = {
     	          + "Name" = "Single-WebSrv"
     	        }
     	     ...중략...
        	
     	  # aws_security_group.instance will be created
     	  + resource "aws_security_group" "instance" {
     	      + arn                    = (known after apply)
     	      + description            = "Managed by Terraform"
     	      + egress                 = (known after apply)
     	      + id                     = (known after apply)
     	      + ingress                = [
     	          + {
     	              + cidr_blocks      = [
     	                  + "0.0.0.0/0",
     	                ]
     	              + description      = ""
     	              + from_port        = 80
     	              + ipv6_cidr_blocks = []
     	              + prefix_list_ids  = []
     	              + protocol         = "tcp"
     	              + security_groups  = []
     	              + self             = false
     	              + to_port          = 80
     	            },
     	        ]
     	      + name                   = "terraform-example-instance"
     	      + name_prefix            = (known after apply)
     	      + owner_id               = (known after apply)
     	      + revoke_rules_on_delete = false
     	      + tags_all               = (known after apply)
     	      + vpc_id                 = (known after apply)
     	    }
        	
     	Plan: 2 to add, 0 to change, 0 to destroy.
        	
     	Changes to Outputs:
     	  + public_ip = (known after apply)
        	
     	─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 
        	
     	Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform    
     	apply" now.
    

    plan을 실행하면 Single-WebSrv라는 tags를 가진 인스턴스와 security group이 생성될 것을 알 수 있다

  4. terraform apply 후, public ip에 접속해 본다

     $ terraform apply -auto-approve
        
     	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" {
     	     ...중략...
     	      + tags                                 = {
     	          + "Name" = "Single-WebSrv"
     	        }
     	      + tags_all                             = {
     	          + "Name" = "Single-WebSrv"
     	        }
     	     ...중략...
        	
     	  # aws_security_group.instance will be created
     	  + resource "aws_security_group" "instance" {
     	      + arn                    = (known after apply)
     	      + description            = "Managed by Terraform"
     	      + egress                 = (known after apply)
     	      + id                     = (known after apply)
     	      + ingress                = [
     	          + {
     	              + cidr_blocks      = [
     	                  + "0.0.0.0/0",
     	                ]
     	              + description      = ""
     	              + from_port        = 80
     	              + ipv6_cidr_blocks = []
     	              + prefix_list_ids  = []
     	              + protocol         = "tcp"
     	              + security_groups  = []
     	              + self             = false
     	              + to_port          = 80
     	            },
     	        ]
     	      + name                   = "terraform-example-instance"
     	      + name_prefix            = (known after apply)
     	      + owner_id               = (known after apply)
     	      + revoke_rules_on_delete = false
     	      + tags_all               = (known after apply)
     	      + vpc_id                 = (known after apply)
     	    }
        	
     	Plan: 2 to add, 0 to change, 0 to destroy.
        	
     	Changes to Outputs:
     	  + public_ip = (known after apply)
     	aws_security_group.instance: Creating...
     	aws_security_group.instance: Creation complete after 2s [id=sg-0e00fc97b5504361a]
     	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-02620b22b13a5dfbd]
        	
     	Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
        	
     	Outputs:
        	
     	public_ip = "3.34.48.45"
    

    Untitled

  5. AWS Console에서 리소스 생성된 것도 확인해 볼 수 있다
    • ap-northeast-2c에 인스턴스 생성

      Untitled 1

    • user data 생성

      Untitled 2

    • tags 지정

      Untitled 3

    • security group 생성

      Untitled 4

  6. 마무리는 terraform destroy로 리소스 삭제!

     Destroy complete! Resources: 2 destroyed.
    

테라폼으로 리소스를 생성해 보면 aws 콘솔에서 ec2를 생성하는 것과 별반 다르지 않다

그저 어떤 필수 값이 들어가야 하는지와 코드 구조에 대해 익숙해 진다면 정말 편리하게 사용할 수 있을 것 같다!

근데 생성하면서 ssh나 ssm 접근에 대한 설정을 깜박한다면 인스턴스를 다시 만들거나 콘솔에서 작업 후 import 기능을 사용해야 할 거 같다??

궁금해서 간단하게 user data 내용만 변경해서 apply해 보니 테라폼은 인스턴스를 in-place 배포로 업데이트하고 인스턴스는 중지 후 재시작을 하였다!

Categories:

Updated:

Leave a comment