iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0

我們進到 IaC 的世界了~那…前面在 AWS 手動建立的各種 resource 怎麼辦?

有兩個選項:

  1. 全部砍掉重新用 terraform 寫!

  2. 把手動建立的 resource import 進 terraform

哪個比較容易呢……?

不好說。

重新用 terraform 寫就要查 terraform resource 的 reference,一點一點把前面手動建立的東西寫出來跟測試,就是用 terraform 把前面做的事情再做一次。這個作法容易踩到的問題是除非了解 AWS web console 幫你做了什麼,不然會在找到對應的 resource 及設定上花不少時間。好處是這樣寫出來並且測試過的 terraform configuration 往往不會有太大問題。

import 是你把現有會動的 resource import 進 terraform,好處是可以保留已經會動的 infrastructure (有時候就是會有各種原因例如宇宙射線太強所以我們不能砍掉重來…) ,問題是可能以為已經 import 完所有 resource,但實際還是有缺,到了新的乾淨環境才發現怎麼這個不會動、那個不會動的東缺西缺。

這邊筆者用 import 把前面手動建立的 infrastructure 加進 terraform,之後就能用 terraform 繼續修改 cloud resource。 (其實是以為 import 比較簡單,結果根本沒有。)

Terraform 1.5 import block

terraform 在 1.5 版推出 import block 功能,可以用 import block 來定義要 import 的 resource,還會自動產生 terraform configuration!

沒這個功能前,要 import 手動建立的 resource 都要先寫出 resource block ⇒ 用 terraform import ⇒ plan 看差異 ⇒ 手動補上 resource block 的參數 ⇒ 直到沒有 changes(說是沒有 changes 但有時候還是可能被 default value 陰到)

1.5 推出 import block 後,可以把 import resource 的操作合併進 plan/apply 的流程,而且不用在那裡用 plan 看差異、補參數。雖然還是會遇到一些 error,但整體來說比原本的 import 方式好多了~

接下來讓我們把前面手動建立的 resource 們都 import 進來吧!

Import ECR repository

先定義 import block,syntax 如下:

import {
    id = [resource 在 cloud 上的 identifier]
    to = [terraform 內 resource 的 id]
}

我們從 ECR repository 開始,id 是 resource 在 cloud 上的 identifier,每種 resource 都不一樣,這裡要參考 resource 文件 aws_ecr_repository 中的 import。ECR repository 的 id 是它的名稱,也就是 my-app

import {
    to = aws_ecr_repository.repo
    id = "my-app"
}

import block 的 to 則是打算產生的 resource block 跟它在 terraform 裡的 id,這邊我們 import 的是 aws_ecr_repository 並且把它的 resource id 訂為 repo

接下來用 plan 指令產生要 import 的 resource 的 configuration:

$ terraform plan -generate-config-out=generated.tf

執行後會看到這樣的畫面:

https://ithelp.ithome.com.tw/upload/images/20230924/20160671svIELRvmwJ.png

產生的 configuration 會在 generated.tf 裡:

# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.

# __generated__ by Terraform from "my-app"
resource "aws_ecr_repository" "repo" {
  force_delete         = null
  image_tag_mutability = "MUTABLE"
  name                 = "my-app"
  tags                 = {}
  tags_all             = {}
  encryption_configuration {
    encryption_type = "AES256"
    kms_key         = null
  }
  image_scanning_configuration {
    scan_on_push = false
  }
}

把它搬到 main.tf ,現在 main.tf 長這樣:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = "~> 1.5"
}

provider "aws" {
  profile = "my"
  region  = "ap-northeast-1"
}

import {
    id = "my-app"
    to = aws_ecr_repository.repo
}

resource "aws_ecr_repository" "repo" {
  force_delete         = null
  image_tag_mutability = "MUTABLE"
  name                 = "my-app"
  tags                 = {}
  tags_all             = {}
  encryption_configuration {
    encryption_type = "AES256"
    kms_key         = null
  }
  image_scanning_configuration {
    scan_on_push = false
  }
}

接著正式 import:

$ terraform apply

看到熟悉的畫面,terraform 準備 import:

https://ithelp.ithome.com.tw/upload/images/20230924/20160671dbWsHcDNj8.png

輸入 yes 後 resource 順利 import:

https://ithelp.ithome.com.tw/upload/images/20230924/20160671TNUyruvneR.png

我們可以用 terraform plan 查看目前的 terraform configuration 跟 AWS 上的 infrastructure 有沒有什麼不同:

https://ithelp.ithome.com.tw/upload/images/20230924/20160671VIBnC6oxMo.png

兩邊是一致的!

這就是用 import block 進行 import resource 跟產生 terraform configuration 的方式,接下來我們要把所有前面我們手動建立的 resource 都 import 進來。


上一篇
Day 13 初探 Terraform
下一篇
Day 15 Terraform import network resource
系列文
AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言