CloudNet@ T101 스터디 진행 후 정리한 글 입니다. |
먼저 아래와 같이 aws에서 EC2를 생성 후 busybox로 http를 실행하는 테라폼 코드를 생성 합니다.
## 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"
}
}
Terraform init (준비)
Terraform 바이너리에는 테라폼의 기본 기능은 포함되어 있지만, AWS, 구글 클라우드 등에 대한 코드는 기본으로 포함되어 있지 않아 init 명령어로 테라폼 코드를 스캔하고, 테라폼 코드에 있는 프로바이더의 필요한 코드를 .terraform 폴더에 다운 받아 작성한 Terraform 코드의 구성을 실행 할 수 있도록 작업 디렉토리를 준비하게 됩니다.
아래를 보면 init 명령어를 한 후 .terraform 디렉토리와 .terraform.lock.hcl 파일이 생성 된 것을 확인 할 수 있으며,
.terraform 디렉토리 안에는 코드에서 사용하겠다고 지정한 aws를 사용할 수 있도록 프로바이더 플로그인을 다운하여 준비한 것을 볼 수 있습니다.
## init 명령어 전 main.tf 파일만 있는 상태
hong@test MINGW64 /d/hong/git/test
$ ll -al
total 1
drwxr-xr-x 1 hong 197121 0 11월 8 23:42 ./
drwxr-xr-x 1 hong 197121 0 11월 8 23:33 ../
-rw-r--r-- 1 hong 197121 389 11월 8 23:33 main.tf
## terraform init 명령어
hong@test MINGW64 /d/hong/git/test
$ terraform.exe init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v4.38.0...
- Installed hashicorp/aws v4.38.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.
## init 명령어 이후 .terraform, .terraform.lock.hcl 파일 생성
.terraform.lock.hcl 파일은 종속성 잠금을 담당하는 파일입니다. 테라폼 0.13 이전의 버전들은 init 명령어 시 관련된 최신 버전의 프로바이더를 가져와 설치되었기 때문에 init 시 프로바이더 버전이 변경되어 문제가 발생하자, 테라폼 0.14 버전에서는 잠금 파일인 .terraform.lock.hcl 파일에 있는 프로바이더 종속 버전만을 기억하여 설치하므로써 이러한 문제를 해결하였습니다.
hong@test MINGW64 /d/hong/git/test
$ ll -al
total 5
drwxr-xr-x 1 hong 197121 0 11월 8 23:42 ./
drwxr-xr-x 1 hong 197121 0 11월 8 23:33 ../
drwxr-xr-x 1 hong 197121 0 11월 8 23:42 .terraform/
-rw-r--r-- 1 hong 197121 1152 11월 8 23:42 .terraform.lock.hcl
-rw-r--r-- 1 hong 197121 389 11월 8 23:33 main.tf
## init 명령어 이후 .terraform 디렉토리의 구조 확인
.terraform 디렉토리 안에는 코드에서 사용하겠다고 지정한 aws를 사용할 수 있도록 프로바이더 플로그인들이 다운된 것을 볼 수 있습니다.
hong@test MINGW64 /d/hong/git/test
$ tree .terraform
.terraform
`-- providers
`-- registry.terraform.io
`-- hashicorp
`-- aws
`-- 4.38.0
`-- windows_amd64
`-- terraform-provider-aws_v4.38.0_x5.exe
Terraform plan (확인)
plan 명령어는 코드가 적용되기 전 테라폼이 수행할 작업을 확인 할 수 있습니다.
아래와 같이 추가되는 항목은 +로, 빠지는 항목은 -로, 변경되는 항목은 ~로 표기됩니다.
hong@test MINGW64 /d/hong/git/test
$ terraform.exe 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)
+ get_password_data = false
+ host_id = (known after apply)
+ host_resource_group_arn = (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 = {
+ "Name" = "terraform-Study-101"
}
+ tags_all = {
+ "Name" = "terraform-Study-101"
}
+ tenancy = (known after apply)
+ user_data = "d91ca31904077f0b641b5dd5a783401396ffbf3f"
+ 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)
+ capacity_reservation_resource_group_arn = (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)
}
+ maintenance_options {
+ auto_recovery = (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_card_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ private_dns_name_options {
+ enable_resource_name_dns_a_record = (known after apply)
+ enable_resource_name_dns_aaaa_record = (known after apply)
+ hostname_type = (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.
terraform apply (생성)
apply 명령어 시 보여주는 내용은 plan 명령어와 같지만,
plan 명령어는 확인만 가능한 반면에 apply 명령어는 실제로 해당 코드를 적용할 수 있습니다.
apply 명령어 시 작업을 수행할 것인지에 대한 물음을 하는데 -auto-approve 옵션을 주게되면 물음 없이 바로 진행도 가능합니다.
hong@test MINGW64 /d/hong/git/test
$ terraform.exe 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)
+ 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)
+ get_password_data = false
+ host_id = (known after apply)
+ host_resource_group_arn = (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 = {
+ "Name" = "terraform-Study-101"
}
+ tags_all = {
+ "Name" = "terraform-Study-101"
}
+ tenancy = (known after apply)
+ user_data = "d91ca31904077f0b641b5dd5a783401396ffbf3f"
+ 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)
+ capacity_reservation_resource_group_arn = (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)
}
+ maintenance_options {
+ auto_recovery = (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_card_index = (known after apply)
+ network_interface_id = (known after apply)
}
+ private_dns_name_options {
+ enable_resource_name_dns_a_record = (known after apply)
+ enable_resource_name_dns_aaaa_record = (known after apply)
+ hostname_type = (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.
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: Creation complete after 21s [id=i-xxxxxxxxxxxxxxx]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
terraform.tfstate 파일
Terraform apply 시 기존에는 없던 terraform.tfstate 파일이 생성 된 것을 확인할 수 있습니다.
hong@test MINGW64 /d/hong/git/test
$ ll
total 13
-rw-r--r-- 1 hong 197121 389 11월 10 12:48 main.tf
-rw-r--r-- 1 hong 197121 178 11월 10 12:55 terraform.tfstate
-rw-r--r-- 1 hong 197121 4516 11월 10 12:55 terraform.tfstate.backup
terraform.tfstate 파일은 json 형태로 테라폼으로 구성 된 인프라의 현재 상태를 저장하고 있는 파일입니다.
- 상태 파일 충돌? 테스트
- main.tf 파일 삭제 후 terraform apply
- 리소스 삭제
- terraform.tfstate 파일 삭제 후 terraform apply
- 리소스 생성 But 리소스가 있으므로 에러 발생
- 이럴 때에는 import 명령어로 terraform.tfstate 파일을 다시 생성 가능
- main.tf 파일 삭제 후 terraform apply
Terraform 내용 변경 (plan, apply)
테라폼의 내용을 변경 후 plan, apply 명령어를 사용하면 아래와 같이 ~ 표시로 변경되는 부분을 확인 할 수 있습니다.
~ resource "aws_instance" "example" {
id = "i-0f7f030e5fcf1e3d8"
~ instance_type = "t2.micro" -> "t3.medieum"
tags = {
"Name" = "terraform-Study-101"
}
hong@test MINGW64 /d/hong/git/test
$ terraform.exe plan
aws_instance.example: Refreshing state... [id=i-xxxxxxxxxxxxxxx]
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-xxxxxxxxxxxxxxx"
~ instance_type = "t2.micro" -> "t3.medieum"
tags = {
"Name" = "terraform-Study-101"
}
# (30 unchanged attributes hidden)
# (7 unchanged blocks hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
terraform destroy (삭제)
terraform destroy는 생성한 리소스들을 삭제하는 명령어 입니다.
destroy 명령어 시에도 apply 명령어와 같이 작업을 수행할 것이지에 대한 물음을하며 -auto-approve 옵션을 주게되면 물음 없이 진행이 가능합니다.
hong@test MINGW64 /d/hong/git/test
$ terraform.exe destroy
aws_instance.example: Refreshing state... [id=i-xxxxxxxxxxxxxxx]
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:xxxxxxxxxxxxxxx:instance/i-0f7f030e5fcf1e3d8" -> 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
- hibernation = false -> null
- id = "i-0f7f030e5fcf1e3d8" -> null
- instance_initiated_shutdown_behavior = "stop" -> null
- instance_state = "running" -> null
- instance_type = "t2.micro" -> null
- ipv6_address_count = 0 -> null
- ipv6_addresses = [] -> null
- monitoring = false -> null
- primary_network_interface_id = "eni-xxxxxxxxxxxxxxx" -> null
- private_dns = "ip-172-31-13-226.ap-northeast-2.compute.internal" -> null
- private_ip = "172.31.13.226" -> null
- public_dns = "ec2-1-1-1-1.ap-northeast-2.compute.amazonaws.com" -> null
- public_ip = "1.1.1.1" -> null
- secondary_private_ips = [] -> null
- security_groups = [
- "default",
] -> null
- source_dest_check = true -> null
- subnet_id = "subnet-xxxxxxxxxxxxxxx" -> null
- tags = {
- "Name" = "terraform-Study-101"
} -> null
- tags_all = {
- "Name" = "terraform-Study-101"
} -> null
- tenancy = "default" -> null
- user_data = "d91ca31904077f0b641b5dd5a783401396ffbf3f" -> null
- user_data_replace_on_change = false -> null
- vpc_security_group_ids = [
- "sg-xxxxxxxxxxxxxxx",
] -> null
- capacity_reservation_specification {
- capacity_reservation_preference = "open" -> null
}
- credit_specification {
- cpu_credits = "standard" -> null
}
- enclave_options {
- enabled = false -> null
}
- maintenance_options {
- auto_recovery = "default" -> null
}
- metadata_options {
- http_endpoint = "enabled" -> null
- http_put_response_hop_limit = 1 -> null
- http_tokens = "optional" -> null
- instance_metadata_tags = "disabled" -> null
}
- private_dns_name_options {
- enable_resource_name_dns_a_record = false -> null
- enable_resource_name_dns_aaaa_record = false -> null
- hostname_type = "ip-name" -> null
}
- root_block_device {
- delete_on_termination = true -> null
- device_name = "/dev/sda1" -> null
- encrypted = false -> null
- iops = 100 -> null
- tags = {} -> null
- throughput = 0 -> null
- volume_id = "vol-xxxxxxxxxxxxxxx" -> 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-xxxxxxxxxxxxxxx]
aws_instance.example: Still destroying... [id=i-xxxxxxxxxxxxxxx, 10s elapsed]
aws_instance.example: Still destroying... [id=i-xxxxxxxxxxxxxxx, 20s elapsed]
aws_instance.example: Destruction complete after 30s
Destroy complete! Resources: 1 destroyed.
Terraform help (위의 명령어 외 추가 명령어들)
$ terraform.exe -help
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.
참고자료
'Newb > Terraform' 카테고리의 다른 글
Trraform으로 지정한 AWS 리소스 비용 계산 해보기 (0) | 2022.12.08 |
---|---|
Terraform으로 AWS에서 많이 사용하는 기본 서비스 구성 구축해보기 (0) | 2022.11.13 |
Terraform ? (0) | 2022.10.30 |