Terraform의 import와 state mv 명령어
Terraform으로 퍼블릭 클라우드를 관리하다 보면 코드를 잘 작성하는 것보다 state를 어떻게 관리할 것인가가 훨씬 중요해 중요해집니다. 저의 경우 주로 AWS의 다양한 서비스를 Terraform코드로 관리하고 있지만 모든 인프라를 코드로 관리하기에 한계가 있습니다. 그리고 콘솔로 생성된 리소스들을 코드에 반영해야 하거나 리소스 코드로 만들어진 state를 모듈로 변경하여 재사용해야 할 경우들이 발생할 때도 있습니다.
그중 import와 rename에 대한 명령어를 정리해 보려고 합니다. 이 작업들은 인프라를 코드로 관리하는 데 매우 중요한 역할을 하며, Terraform 상태 파일과 코드 간의 일관성을 유지하는 데 큰 도움을 줍니다.
Resource Import
Terraform은 기본적으로 코드에 정의된 리소스를 관리합니다. 그러나 이미 존재하는 리소스가 있을 경우, Terraform 코드에 추가하지 않고도 해당 리소스를 Terraform 관리 하에 두기 위해 `terraform import` 명령을 사용합니다. `terraform import`는 기존 인프라 리소스를 Terraform 상태 파일에 추가합니다.
우선, Terraform 코드에서 리소스를 정의합니다.
예를 들어, S3 버킷이 이미 존재하는 경우 이를 Terraform 코드로 우선 정의합니다.
# hcl
resource "aws_s3_bucket" "my_bucket" {
bucket = "existing-bucket-name"
}
그리고 리소스를 Terraform 상태에 가져오려면, Terraform `import` 명령을 사용합니다.
# bash
terraform import aws_s3_bucket.my_bucket existing-bucket-name
이 명령은 `existing-bucket-name`이라는 S3 버킷을 `aws_s3_bucket.my_bucket` 리소스로 Terraform 상태 파일에 추가합니다.
Import 후, `terraform plan`을 실행하여 상태 파일과 실제 인프라가 일치하는지 확인합니다.
*보통의 경우 이때 설정된 필수 정보값들이 지정되지 않았다는 error 메시지를 보게 될 것입니다. 이때 필수 변숫값을 추가 리소스에 적합하게 작성하여 다시 plan으로 확인하여 일치하게 해 주면 이후부터는 테라폼코드 import 한 리소스를 관리할 수 있습니다.
Rename
`terraform state mv` 명령어를 사용하여 Terraform 상태 파일에서 리소스의 이름을 변경할 수 있습니다. 이는 리소스를 다른 이름으로 변경하거나, 모듈 내외로 이동할 때 유용합니다. 이 작업은 상태 파일 내에서 참조를 수정하여 Terraform이 리소스를 올바르게 관리할 수 있도록 합니다.
리소스의 이름을 변경하고자 할 때 아래와 같은 명령어를 사용합니다.
# bash
terraform state mv aws_s3_bucket.my_bucket aws_s3_bucket.new_bucket_name
이 명령은 `aws_s3_bucket.my_bucket`을 상태 파일에서 `aws_s3_bucket.new_bucket_name`으로 이름을 변경합니다.
리소스를 모듈로 이동하려면 다음과 같이 실행합니다.
# bash
terraform state mv aws_s3_bucket.new_bucket_name module.my_module.aws_s3_bucket.my_bucket
이 명령은 `aws_s3_bucket.new_bucket_name`을 `module.my_module.aws_s3_bucket.my_bucket`으로 상태 파일에서 이동합니다.
*이름을 변경한 후에는 코드에서도 해당 리소스의 참조를 수정하고 `terraform plan`을 통해 상태와 코드를 맞춰주어야 합니다.
Resource를 Module로 전환
기존에 개별 리소스로 관리되던 인프라를 모듈로 관리하려는 경우, 리소스를 모듈로 이동시키기 위해 사용합니다. 이 작업은 `terraform state mv`와 유사하지만, 특정 모듈의 네임스페이스로 리소스를 이동하는 데 중점을 둡니다.
1. 모듈을 정의하고 리소스를 이동할 준비를 합니다. 예를 들어, `my_module` 모듈을 정의하고 그 안에 S3 버킷 리소스를 포함시킵니다.
# hcl
module "my_module" {
source = "./modules/my_module"
}
2. `terraform state mv` 명령을 사용하여 기존 리소스를 모듈로 이동시킵니다.
# bash
terraform state mv aws_s3_bucket.my_bucket module.my_module.aws_s3_bucket.my_bucket
이 명령은 `aws_s3_bucket.my_bucket`을 `module.my_module.aws_s3_bucket.my_bucket`으로 상태 파일에서 이동합니다.
3. Terraform 코드에서 리소스를 모듈로 정의한 후, `terraform plan`을 실행하여 상태와 코드가 일치하는지 확인합니다.
그리고 코드화가 되기전 콘솔에서 작성된 리소스를 하나하나 import하고 rename하기 어렵다면 아래 코드를 사용해보길 추천한다.
(terraformer) https://github.com/GoogleCloudPlatform/terraformer