Windows 10 환경에서 Terraform을 이용한 AWS 자원 배포 - 2. 기본 EC2 배포
Terraform이란?
Terraform은 Go언어로 개발된 오픈 소스 도구로, Terraform에서 지원하는 OS, 클라우드 플랫폼에 맞춰
Terraform 바이너리 파일을 통해 API를 호출해 자원을 관리함
Terrform 동작과정
Terraform의 동작은 크게 3가지로 Write, Plan, Apply 단계로 나뉨
- Write: You define resources, which may be across multiple cloud providers and services. For example, you might create a configuration to deploy an application on virtual machines in a Virtual Private Cloud (VPC) network with security groups and a load balancer.
- Plan: Terraform creates an execution plan describing the infrastructure it will create, update, or destroy based on the existing infrastructure and your configuration.
- Apply: On approval, Terraform performs the proposed operations in the correct order, respecting any resource dependencies. For example, if you update the properties of a VPC and change the number of virtual machines in that VPC, Terraform will recreate the VPC before scaling the virtual machines.
위의 내용을 간단하게 말하면 아래와 같다.
- IaC 코드를 작성(Write)하고
- 작성한 코드를 사전 적용해 계획(Plan)을 세우고
- 코드를 클라우드 플랫폼 자원에 적용(Apply) 한다
엄밀하게 말하면 1번 Write 전에 Initialize 단계가 존재하나 Initialize는 최초 작업 시만 사용하는 것으로 보임
Terraform을 이용한 EC2 배포 실습
실습 전 준비사항(2가지)
- AWS 계정(Free-Tier) 및 해당 계정에 default VPC가 존재
아래의 실습 과정은 사전에 default VPC가 생성되어있어야 하므로
default VPC가 삭제되었다면 아래의 과정을 통해 생성
- AWS IAM을 통해 Access Key 생성
간단한 실습이므로 AdministratorAccess권한을 부여해서 실습함
실무일 경우엔 필요한 최소권한부여를 권장함
생성한 Access Key와 Secret Key를 각각 아래와 같이 설정
c:\terraform_study>aws configure
AWS Access Key ID [None]: ********************
AWS Secret Access Key [None]: ***************************************
Default region name [None]: ap-northeast-2
Default output format [None]:
c:\terraform_study>aws configure list
Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key ****************Z7JM shared-credentials-file
secret_key ****************9tbA shared-credentials-file
region ap-northeast-2 config-file ~/.aws/config
c:\terraform_study>
위의 2가지 작업이 완료된 후 검증을 위한 AWS CLI 명령어 수행
c:\terraform_study>aws ec2 describe-vpcs --filter Name=isDefault,Values=true | jq ".Vpcs[0].VpcId"
"vpc-08fcf3b1307525e7c"
-> 위와 같이 default VPC의 ID가 확인되어야 정상
Terraform으로 EC2 배포 수행
1. Terraform 코드 작성 (Write단계)
메모장에 작성해도 무방하며 임의의 폴더를 생성하고 해당 폴더에서 main.tf 파일과 userdata-web.txt 파일을 생성해 아래의 내용을 작성
// main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-0e9bfdb247cc8de84"
instance_type = "t2.micro"
user_data = <<-EOF
#!/bin/bash
echo "Hello, T101 Study" > index.html
nohup busybox httpd -f -p 8080 &
EOF
tags = {
Name = "terraform-Study-101"
}
}
// userdata-web.txt
#!/bin/bash
echo "Hello, T101 Study" > index.html
nohup busybox httpd -f -p 8080 &
메모장 작성이 귀찮을 경우 cmd 창에서 작업폴더로 이동해 아래의 명령을 수행
echo provider "aws" { > main.tf
echo region = "ap-northeast-2" >> main.tf
echo } >> main.tf
echo. >> main.tf
echo resource "aws_instance" "example" { >> main.tf
echo ami = "ami-0e9bfdb247cc8de84" >> main.tf
echo instance_type = "t2.micro" >> main.tf
echo. >> main.tf
echo user_data = "${file("userdata-web.txt")}" >> main.tf
echo. >> main.tf
echo tags = { >> main.tf
echo Name = "terraform-Study-101" >> main.tf
echo } >> main.tf
echo } >> main.tf
type main.tf
echo #!/bin/bash > userdata-web.txt
echo echo "Hello, T101 Study" > index.html >> userdata-web.txt
echo nohup busybox httpd -f -p 8080 ^& >> userdata-web.txt
type userdata-web.txt
2. Terraform 코드 초기화 수행 및 사전 적용 (Plan)
c:\terraform_study\study1>terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v4.36.1...
- Installed hashicorp/aws v4.36.1 (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.
c:\terraform_study\study1>
c:\terraform_study\study1>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-0e9bfdb247cc8de84"
+ 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_stop = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (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.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
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.
c:\terraform_study\study1>
중요하게 봐야하는 사항은 plan을 통해서 어떻게 동작하는지 심볼을 표시해주는 것이며,
이번 실습에서는 EC2 생성을 수행하므로 create되는 + 표기 부분을 확인할 수 있음
3. Terraform 적용 (Apply)
기존 plan 시 출력되었던 화면이 한번 더 출력되고, 진행여부를 묻는 프롬프트가 추가로 발생
yes를 입력하면 작성한 리소스를 생성함
c:\terraform_study\study1>terraform apply
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-0e9bfdb247cc8de84"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
...
...
...
+ volume_type = (known after apply)
}
}
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: 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: Still creating... [40s elapsed]
aws_instance.example: Creation complete after 41s [id=i-0de2eda5dae07a694]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
c:\terraform_study\study1>
4. Terraform 삭제(destory)
c:\terraform_study\study1>terraform destroy
aws_instance.example: Refreshing state... [id=i-0de2eda5dae07a694]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
- destroy
Terraform will perform the following actions:
# aws_instance.example will be destroyed
- resource "aws_instance" "example" {
- ami = "ami-0e9bfdb247cc8de84" -> null
- arn = "arn:aws:ec2:ap-northeast-2:411158671563:instance/i-0de2eda5dae07a694" -> null
- associate_public_ip_address = true -> null
- availability_zone = "ap-northeast-2a" -> null
- cpu_core_count = 1 -> null
- cpu_threads_per_core = 1 -> null
- disable_api_stop = false -> null
- disable_api_termination = false -> null
- ebs_optimized = false -> null
- get_password_data = false -> null
...
...
...
- tags = {} -> null
- throughput = 0 -> null
- volume_id = "vol-0df8deb0eb8c04716" -> null
- volume_size = 8 -> null
- volume_type = "gp2" -> null
}
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_instance.example: Destroying... [id=i-0de2eda5dae07a694]
aws_instance.example: Still destroying... [id=i-0de2eda5dae07a694, 10s elapsed]
aws_instance.example: Still destroying... [id=i-0de2eda5dae07a694, 20s elapsed]
aws_instance.example: Destruction complete after 29s
Destroy complete! Resources: 1 destroyed.
c:\terraform_study\study1>
5. 수행결과 모니터링
실습 전에 준비가 끝난 상태에서 아래의 명령을 수행해두면,
모니터링을 통해 EC2 서버가 생성되는지 여부를 확인할 수 있다.
모니터링을 위한 cmd 창에 아래의 명령어 수행
for /l %g in () do @( ^
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text & echo "------------------------------" & timeout /t 1)
// EC2 생성 전
c:\terraform_study>for /l %g in () do @( ^
More? aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text & echo "------------------------------" & timeout /t 1)
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
1 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
...
...
...
// EC2 생성 후
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
terraform-Study-101 3.38.92.236 running
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
terraform-Study-101 3.38.92.236 running
"------------------------------"
...
...
...
// EC2 삭제 후
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
0 초 기다리는 중, 계속하려면 아무 키나 누르십시오 ...
"------------------------------"
실제 AWS 화면에서도 정상적으로 EC2가 생성된 것을 확인해볼 수 있다
Terraform 작업 폴더를 확인해보면 .terraform 폴더와 .terraform.lock.hcl, terraform.tfstate 파일이 자동으로 생성된 것을 확인할 수 있음
- .terraform 폴더는 terraform을 수행하기 위해 각 클라우드 플랫폼 별 플러그인과 모듈을 관리하는 폴더
- .terraform.lock.hcl 파일은 terraform init을 수행할 때 플랫폼 별 모듈의 버전 고정(Dependency Lock)하는데 사용한다고 함
- terraform 명령을 통해서 생성한 자원의 상태정보를 기록하는 파일이며, 해당 파일정보가 실제 자원 상태랑 일치하도록 관리해야한다고 함
c:\terraform_study\study1>dir
Volume in drive C has no label.
Volume Serial Number is 508A-A44B
Directory of c:\terraform_study\study1
2022-10-23 오전 12:23 <DIR> .
2022-10-23 오전 12:23 <DIR> ..
2022-10-23 오전 12:17 <DIR> .terraform
2022-10-23 오전 12:17 1,152 .terraform.lock.hcl
2022-10-23 오전 12:17 756 main.tf
2022-10-23 오전 12:23 4,516 terraform.tfstate
2022-10-23 오전 12:17 148 userdata-web.txt
4 File(s) 6,572 bytes
3 Dir(s) 53,103,104,000 bytes free
c:\terraform_study\study1>
위의 파일은 Terraform 사용에 있어 아주 중요하다고 생각되므로
상세한 내용을 스터디를 더 진행한 후 별도로 작성하도록 함
참고자료
- 테라폼 공식 홈페이지 : https://developer.hashicorp.com/terraform/intro
- 테라폼 user data 파일입력 관련 참고 : https://multicloud.tistory.com/m/52
- 윈도우 cmd에서 명령어 반복 수행 : https://ss64.com/nt/for.html