今まで、VMware、Azure、AWSと触ってきましたが、一切自動化というのをしてきていませんでした。
先日、Google Cloudを初めて触った際に同僚からTerraform使うと構築楽だよと言われ触ったところ、構築した環境をコマンド一つで削除できることに感動しました。
業務では、構築がうまくいかない場合、作業を切り戻すこともあり、その手順も調べながら作成していましたが、Terraformは、あらかじめて設定した内容を「apply」で実行し、作業前の状態に戻すのを「destroy」というコマンドだけで実現できます。
これをVMwareの製品でも実現したいと思い、NSXALBのVS作成手順を調べたので紹介します。
ネットワーク構成
ネットワーク構成は、vSphere7で構築したホームラボ環境を利用します。
今回、赤字で記載しているVIPへアクセスすると、2台のLinuxサーバに負荷分散される環境を作っていきます。
Terraformのインストール
ダウンロードと配置
今回、Terraformを実行する端末は、WIndows10になるため、Windows版のTerraformをインストールします。
Terraformの公式サイトから、環境に合わせてダウンロードします。
developer.hashicorp.com
ダウンロードしたファイルを解凍し、実行ファイルを任意の場所に配置します。
今回は、「c:\work\Terraform\alb」配下に「terraform.exe」を配置しました。
c:\work\Terraform\alb> c:\work\Terraform\alb>dir 2024/01/14 22:45 <DIR> . 2024/01/14 22:45 <DIR> .. 2023/12/13 18:11 82,848,432 terraform.exe 1 個のファイル 82,848,432 バイト 2 個のディレクトリ 663,619,153,920 バイトの空き領域 c:\work\Terraform\alb>
Pathを通す
Pathを通すために環境変数の設定を行います。
[コントロールパネル]-[システムとセキュリティ]-[システム]-[システムの詳細設定]から「環境変数」をクリックします。
変数の「Path」を選択し、編集をクリックします。
新規から画面のように「Terraform.exe」を配置したフォルダを設定します。
設定後は、全て「OK」をクリックして設定を閉じます。
コマンドプロンプトを起動し、Pathが通っていることを確認します。
正しく設定されていれば、Terraformのバージョンが表示されます。
C:\Users\hippi>terraform -v Terraform v1.6.6 on windows_amd64 C:\Users\hippi>
tfファイルの作成
設定を投入するための設定ファイル(tfファイル)を作成します。
providerファイルの作成
最初にNSXALBに接続するための情報を「Provider.tf」として作成します。
拡張子を.tfとしたテキストファイルを作成し、以下の情報を貼り付けます。
#NSXALB接続定義 terraform { required_providers { avi = { source = "vmware/avi" version = "22.1.3" } } } #認証情報設定 provider "avi" { avi_controller = "avi51.home.local" avi_tenant = "admin" #ユーザー名を設定 avi_username = "xxxxxx" #パスワードを設定 avi_password = "xxxxxx" avi_version = "22.1.3" }
mainファイルの作成
Pool、VIP、VSの情報を「main.tf」として作成します。
拡張子を.tfとしたテキストファイルを作成し、以下の情報を貼り付けます。
#Tenant情報取得 data "avi_tenant" "admin" { name = "admin" } #Clouds情報取得 data "avi_cloud" "default_cloud" { name = "Defaul-Cloud" tenant_ref = data.avi_tenant.admin.id } #vrf情報取得 data "avi_vrfcontext" "vrf01" { name = "vrf01" tenant_ref = data.avi_tenant.admin.id } #HealthMonitor作成 resource "avi_healthmonitor" "monitor" { name = "custom-HTTP" type = "HEALTH_MONITOR_HTTP" send_interval = "5" receive_timeout = "4" successful_checks = "2" failed_checks = "2" } #Pool作成 resource "avi_pool" "pool01" { name = "pool_http" tenant_ref = data.avi_tenant.admin.id cloud_ref = data.avi_cloud.default_cloud.id vrf_ref = data.avi_vrfcontext.vrf01.id lb_algorithm = "LB_ALGORITHM_ROUND_ROBIN" health_monitor_refs = [avi_healthmonitor.monitor.id] servers { ip { type = "V4" addr = "192.168.10.71" } port = 80 } servers { ip { type = "V4" addr = "192.168.10.72" } port = 80 } } #VIP作成 resource "avi_vsvip" "vip01" { name = "VIP_192.168.3.11" vip { vip_id = "0" ip_address { type = "V4" addr = "192.168.3.11" } auto_allocate_ip = false } tenant_ref = data.avi_tenant.admin.id cloud_ref = data.avi_cloud.default_cloud.id vrf_context_ref = data.avi_vrfcontext.vrf01.id } #VS作成 resource "avi_virtualservice" "vs01" { name = "vs_http" tenant_ref = data.avi_tenant.admin.id pool_ref = avi_pool.pool01.id vsvip_ref = avi_vsvip.vip01.id cloud_ref = data.avi_cloud.default_cloud.id vrf_context_ref = data.avi_vrfcontext.vrf01.id cloud_type = "CLOUD_NONE" services { port = 80 enable_ssl = false } }
リソースの作成
事前の設定が完了したので、実際にコマンドを実行してリソースを作成していきます。
初期化&プラグインのインストール(teraform init)
まず最初に、作成したtfファイルのあるディレクトリに移動し、「terraform init」を実行します。
これは、Terraform 構成ファイルを含む作業ディレクトリを初期化し、必要なプラグインやモジュールのインストールをしてくれます。
PS C:\work\Terraform\alb> PS C:\work\Terraform\alb> terraform init Initializing the backend... Initializing provider plugins... - Reusing previous version of vmware/avi from the dependency lock file - Using previously-installed vmware/avi v22.1.3 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. PS C:\work\Terraform\alb> PS C:\work\Terraform\alb>
実行計画(terraform plan)
続いて、「terraform plan」を実行します。
これは、リソースを作成する実行計画にあたるもので、どのようなリソースに対してどのような設定を行うかあらかじめ表示してくれます。
もし、コードに問題があれば、どこでエラーが発生しているか教えてくれます。
PS C:\work\Terraform\alb> PS C:\work\Terraform\alb> terraform plan data.avi_tenant.admin: Reading... data.avi_tenant.admin: Read complete after 0s [id=https://avi51.home.local/api/tenant/admin] data.avi_vrfcontext.vrf01: Reading... data.avi_cloud.default_cloud: Reading... data.avi_vrfcontext.vrf01: Read complete after 0s [id=https://avi51.home.local/api/vrfcontext/vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab] data.avi_cloud.default_cloud: Read complete after 0s 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: # avi_healthmonitor.monitor will be created + resource "avi_healthmonitor" "monitor" { + allow_duplicate_monitors = (known after apply) + description = (known after apply) + disable_quickstart = (known after apply) + failed_checks = "2" + id = (known after apply) + is_federated = "false" + monitor_port = (known after apply) + name = "custom-HTTP" + receive_timeout = "4" + send_interval = "5" + successful_checks = "2" + tenant_ref = (known after apply) + type = "HEALTH_MONITOR_HTTP" + uuid = (known after apply) } # avi_pool.pool01 will be created + resource "avi_pool" "pool01" { + analytics_profile_ref = (known after apply) + append_port = "NON_DEFAULT_80_443" + application_persistence_profile_ref = (known after apply) + autoscale_launch_config_ref = (known after apply) + autoscale_policy_ref = (known after apply) + capacity_estimation = "false" + capacity_estimation_ttfb_thresh = "0" + cloud_config_cksum = (known after apply) + cloud_ref = (known after apply) + connection_ramp_duration = "10" + created_by = (known after apply) + default_server_port = "80" + delete_server_on_dns_refresh = "true" + description = (known after apply) + east_west = (known after apply) + enable_http2 = "false" + enabled = "true" + fewest_tasks_feedback_delay = "10" + graceful_disable_timeout = "1" + gslb_sp_enabled = (known after apply) + health_monitor_refs = (known after apply) + host_check_enabled = "false" + id = (known after apply) + ignore_server_port = "false" + ignore_servers = false + inline_health_monitor = "true" + ipaddrgroup_ref = (known after apply) + lb_algo_rr_per_se = "false" + lb_algorithm = "LB_ALGORITHM_ROUND_ROBIN" + lb_algorithm_consistent_hash_hdr = (known after apply) + lb_algorithm_core_nonaffinity = "2" + lb_algorithm_hash = "LB_ALGORITHM_CONSISTENT_HASH_SOURCE_IP_ADDRESS" + lookup_server_by_name = "false" + max_concurrent_connections_per_server = "0" + min_health_monitors_up = (known after apply) + min_servers_up = (known after apply) + name = "pool_http" + pki_profile_ref = (known after apply) + pool_type = "POOL_TYPE_GENERIC_APP" + request_queue_depth = "128" + request_queue_enabled = "false" + resolve_pool_by_dns = (known after apply) + rewrite_host_header_to_server_name = "false" + rewrite_host_header_to_sni = "false" + routing_pool = "false" + server_disable_type = "DISALLOW_NEW_CONNECTION" + server_name = (known after apply) + server_timeout = "0" + service_metadata = (known after apply) + sni_enabled = "true" + ssl_key_and_certificate_ref = (known after apply) + ssl_profile_ref = (known after apply) + tenant_ref = "https://avi51.home.local/api/tenant/admin" + tier1_lr = (known after apply) + use_service_port = "false" + use_service_ssl_mode = "false" + uuid = (known after apply) + vrf_ref = "https://avi51.home.local/api/vrfcontext/vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab" + servers { + autoscaling_group_name = (known after apply) + availability_zone = (known after apply) + description = (known after apply) + enabled = "true" + external_orchestration_id = (known after apply) + external_uuid = (known after apply) + hostname = (known after apply) + mac_address = (known after apply) + nw_ref = (known after apply) + port = "80" + preference_order = (known after apply) + prst_hdr_val = (known after apply) + ratio = "1" + resolve_server_by_dns = "false" + rewrite_host_header = "false" + server_node = (known after apply) + static = "false" + verify_network = "false" + vm_ref = (known after apply) + ip { + addr = "192.168.10.71" + type = "V4" } } + servers { + autoscaling_group_name = (known after apply) + availability_zone = (known after apply) + description = (known after apply) + enabled = "true" + external_orchestration_id = (known after apply) + external_uuid = (known after apply) + hostname = (known after apply) + mac_address = (known after apply) + nw_ref = (known after apply) + port = "80" + preference_order = (known after apply) + prst_hdr_val = (known after apply) + ratio = "1" + resolve_server_by_dns = "false" + rewrite_host_header = "false" + server_node = (known after apply) + static = "false" + verify_network = "false" + vm_ref = (known after apply) + ip { + addr = "192.168.10.72" + type = "V4" } } } # avi_virtualservice.vs01 will be created + resource "avi_virtualservice" "vs01" { + active_standby_se_tag = "ACTIVE_STANDBY_SE_1" + advertise_down_vs = "false" + allow_invalid_client_cert = "false" + analytics_profile_ref = (known after apply) + application_profile_ref = (known after apply) + azure_availability_set = (known after apply) + bot_policy_ref = (known after apply) + bulk_sync_kvcache = "false" + close_client_conn_on_config_update = "false" + cloud_config_cksum = (known after apply) + cloud_ref = (known after apply) + cloud_type = "CLOUD_NONE" + created_by = (known after apply) + delay_fairness = "false" + description = (known after apply) + east_west_placement = "false" + enable_autogw = "true" + enable_rhi = (known after apply) + enable_rhi_snat = (known after apply) + enabled = "true" + error_page_profile_ref = (known after apply) + flow_dist = "LOAD_AWARE" + flow_label_type = "NO_LABEL" + fqdn = (known after apply) + host_name_xlate = (known after apply) + id = (known after apply) + ign_pool_net_reach = "false" + limit_doser = "false" + max_cps_per_client = "0" + microservice_ref = (known after apply) + min_pools_up = (known after apply) + name = "vs_http" + network_profile_ref = (known after apply) + network_security_policy_ref = (known after apply) + pool_group_ref = (known after apply) + pool_ref = (known after apply) + remove_listening_port_on_vs_down = "false" + scaleout_ecmp = "false" + se_group_ref = (known after apply) + security_policy_ref = (known after apply) + server_network_profile_ref = (known after apply) + service_metadata = (known after apply) + ssl_profile_ref = (known after apply) + ssl_sess_cache_avg_size = "1024" + sso_policy_ref = (known after apply) + tenant_ref = "https://avi51.home.local/api/tenant/admin" + test_se_datastore_level_1_ref = (known after apply) + traffic_clone_profile_ref = (known after apply) + traffic_enabled = "true" + type = "VS_TYPE_NORMAL" + use_bridge_ip_as_vip = "false" + use_vip_as_snat = "false" + uuid = (known after apply) + vh_parent_vs_ref = (known after apply) + vh_type = "VS_TYPE_VH_SNI" + vrf_context_ref = "https://avi51.home.local/api/vrfcontext/vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab" + vsvip_cloud_config_cksum = (known after apply) + vsvip_ref = (known after apply) + waf_policy_ref = (known after apply) + weight = "1" + services { + enable_http2 = "false" + enable_ssl = "false" + horizon_internal_ports = "false" + is_active_ftp_data_port = "false" + override_application_profile_ref = (known after apply) + override_network_profile_ref = (known after apply) + port = "80" + port_range_end = "0" } } # avi_vsvip.vip01 will be created + resource "avi_vsvip" "vip01" { + cloud_ref = (known after apply) + east_west_placement = "false" + id = (known after apply) + name = "VIP_192.168.3.11" + tenant_ref = "https://avi51.home.local/api/tenant/admin" + tier1_lr = (known after apply) + uuid = (known after apply) + vrf_context_ref = "https://avi51.home.local/api/vrfcontext/vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab" + vsvip_cloud_config_cksum = (known after apply) + vip { + auto_allocate_floating_ip = "false" + auto_allocate_ip = "false" + auto_allocate_ip_type = "V4_ONLY" + availability_zone = (known after apply) + avi_allocated_fip = "false" + avi_allocated_vip = "false" + enabled = "true" + floating_subnet6_uuid = (known after apply) + floating_subnet_uuid = (known after apply) + network_ref = (known after apply) + port_uuid = (known after apply) + prefix_length = "32" + subnet6_uuid = (known after apply) + subnet_uuid = (known after apply) + vip_id = "0" + ip_address { + addr = "192.168.3.11" + type = "V4" } } } Plan: 4 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. PS C:\work\Terraform\alb> PS C:\work\Terraform\alb>
実行結果から、「Plan: 4 to add, 0 to change, 0 to destroy.」4つのリソースを追加するという表示が出ており、エラーも内情であることを確認できます。
リソースの作成(terraform apply)
実行計画に問題がないことを確認したら、「terraform apply」を実行してリソースを作成します。
途中で、「Enter a value:」という表示が出たら、「yes」を入力してEnterキーを押下するとリソースが作成されます。
PS C:\work\Terraform\alb> terraform apply data.avi_tenant.admin: Reading... data.avi_tenant.admin: Read complete after 1s [id=https://avi51.home.local/api/tenant/admin] data.avi_vrfcontext.vrf01: Reading... data.avi_cloud.default_cloud: Reading... data.avi_cloud.default_cloud: Read complete after 0s data.avi_vrfcontext.vrf01: Read complete after 0s [id=https://avi51.home.local/api/vrfcontext/vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab] ~省略~ Plan: 4 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: <strong>yes</strong> avi_healthmonitor.monitor: Creating... avi_vsvip.vip01: Creating... avi_healthmonitor.monitor: Creation complete after 0s [id=https://avi51.home.local/api/healthmonitor/healthmonitor-33542429-cf4d-4d8f-b9f9-22578b353e2d] avi_pool.pool01: Creating... avi_vsvip.vip01: Creation complete after 1s [id=https://avi51.home.local/api/vsvip/vsvip-15586354-ed1f-41d4-bb5d-b2d358a858fe] avi_pool.pool01: Creation complete after 1s [id=https://avi51.home.local/api/pool/pool-55d4b021-fca5-481a-98ef-621e9fd046fc] avi_virtualservice.vs01: Creating... avi_virtualservice.vs01: Creation complete after 0s [id=https://avi51.home.local/api/virtualservice/virtualservice-aa1e84d4-ce26-4106-8198-1bb504565419] Apply complete! Resources: 4 added, 0 changed, 0 destroyed. PS C:\work\Terraform\alb>
最終行に「Apply complete!」と表示されていたら作成成功になります。
実行結果の確認
実際にGUIで確認するとリソースが作成されていることが確認できました。
リソースの削除(terraform destroy)
作成したリソースを削除する場合は、「terraform destroy」を実行します。
このコマンドを実行すると「terraform apply」で作成したリソースをすべて削除できます。
PS C:\work\Terraform\alb> PS C:\work\Terraform\alb> terraform destroy data.avi_tenant.admin: Reading... avi_healthmonitor.monitor: Refreshing state... [id=https://avi51.home.local/api/healthmonitor/healthmonitor-33542429-cf4d-4d8f-b9f9-22578b353e2d] data.avi_tenant.admin: Read complete after 1s [id=https://avi51.home.local/api/tenant/admin] data.avi_vrfcontext.vrf01: Reading... data.avi_cloud.default_cloud: Reading... data.avi_vrfcontext.vrf01: Read complete after 0s [id=https://avi51.home.local/api/vrfcontext/vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab] data.avi_cloud.default_cloud: Read complete after 0s avi_vsvip.vip01: Refreshing state... [id=https://avi51.home.local/api/vsvip/vsvip-15586354-ed1f-41d4-bb5d-b2d358a858fe] avi_pool.pool01: Refreshing state... [id=https://avi51.home.local/api/pool/pool-55d4b021-fca5-481a-98ef-621e9fd046fc] avi_virtualservice.vs01: Refreshing state... [id=https://avi51.home.local/api/virtualservice/virtualservice-aa1e84d4-ce26-4106-8198-1bb504565419] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy ~省略~ Plan: 0 to add, 0 to change, 4 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 avi_virtualservice.vs01: Destroying... [id=https://avi51.home.local/api/virtualservice/virtualservice-aa1e84d4-ce26-4106-8198-1bb504565419] avi_virtualservice.vs01: Destruction complete after 0s avi_vsvip.vip01: Destroying... [id=https://avi51.home.local/api/vsvip/vsvip-15586354-ed1f-41d4-bb5d-b2d358a858fe] avi_pool.pool01: Destroying... [id=https://avi51.home.local/api/pool/pool-55d4b021-fca5-481a-98ef-621e9fd046fc] avi_vsvip.vip01: Destruction complete after 0s avi_pool.pool01: Destruction complete after 0s avi_healthmonitor.monitor: Destroying... [id=https://avi51.home.local/api/healthmonitor/healthmonitor-33542429-cf4d-4d8f-b9f9-22578b353e2d] avi_healthmonitor.monitor: Destruction complete after 0s Destroy complete! Resources: 4 destroyed. PS C:\work\Terraform\alb>
コマンドが正常に処理され、リソースが削除されたことが確認できました。
便利なツールやコマンド
tfファイルは、テキストエディタで作成することができますが、コードエディタを使用すると、コードの入力補完やコマンドの実行もできてしまう優れものです。
Visual Studio Code
Microsoft社が無償で提供しているコードエディタです。
私もこれを利用してコードをの作成や実行をしています。
特に「表示」から「ターミナル」を選択すると、画面下部にコマンドプロンプトが表示されるので、コードの作成や修正をしながら、すぐにplan、apply、destroy を実行できるのは便利です。
terraform show
「terraform show」コマンドは、適用済みの全リソースの情報を確認することができます。
コードを作成する際に、パラメーターの名称がわからない時など、基本のパラメータのみTerraformで実行し、その後、GUIで設定してこのコマンドを事項すると、どのパラメータに作成されたか確認することができます。
PS C:\work\Terraform\alb> terraform show
# data.avi_cloud.default_cloud:
data "avi_cloud" "default_cloud" {}
# data.avi_tenant.admin:
data "avi_tenant" "admin" {
config_settings = []
configpb_attributes = []
id = "https://avi51.home.local/api/tenant/admin"
name = "admin"
uuid = "admin"
}
# data.avi_vrfcontext.vrf01:
data "avi_vrfcontext" "vrf01" {
bfd_profile = []
bgp_profile = []
cloud_ref = "https://avi51.home.local/api/cloud/cloud-660ea483-4e48-41d4-882b-75df0b1da3bb"
configpb_attributes = []
debugvrfcontext = []
id = "https://avi51.home.local/api/vrfcontext/vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab"
internal_gateway_monitor = []
name = "vrf01"
static_routes = [
{
disable_gateway_monitor = ""
if_name = ""
labels = []
next_hop = [
{
addr = "192.168.3.1"
type = "V4"
},
]
prefix = [
{
ip_addr = [
{
addr = "0.0.0.0"
type = "V4"
},
]
mask = "0"
},
]
route_id = "1"
},
]
tenant_ref = "https://avi51.home.local/api/tenant/admin"
uuid = "vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab"
}
terraform state show
「terraform state show」コマンドは、指定したリソースだけの情報を確認することができます。
例えば、VIPの情報だけ取得したい場合は、以下のようにコマンドを実行します。
PS C:\work\Terraform\alb> PS C:\work\Terraform\alb> terraform state show avi_vsvip.vip01 # avi_vsvip.vip01: resource "avi_vsvip" "vip01" { cloud_ref = "https://avi51.home.local/api/cloud/cloud-660ea483-4e48-41d4-882b-75df0b1da3bb" east_west_placement = "false" id = "https://avi51.home.local/api/vsvip/vsvip-9ed7e1f9-1f0c-4d48-b04b-a56d53d4da7b" name = "VIP_192.168.3.11" tenant_ref = "https://avi51.home.local/api/tenant/admin" uuid = "vsvip-9ed7e1f9-1f0c-4d48-b04b-a56d53d4da7b" vrf_context_ref = "https://avi51.home.local/api/vrfcontext/vrfcontext-bf0c8942-5281-4505-8056-3b73119a0cab" vip { auto_allocate_floating_ip = "false" auto_allocate_ip = "false" auto_allocate_ip_type = "V4_ONLY" avi_allocated_fip = "false" avi_allocated_vip = "false" enabled = "true" prefix_length = "32" vip_id = "0" ip_address { addr = "192.168.3.11" type = "V4" } } } PS C:\work\Terraform\alb>
terraform fmt
「terraform fmt」コマンドは、コードの体裁を自動的に整えてくれます。
コマンド実行前後で比較してみましょう。
★コマンド実行前 resource "avi_vsvip" "vip01" { name = "VIP_192.168.3.11" vip { vip_id = "0" ip_address { type = "V4" addr = "192.168.3.11" } auto_allocate_ip = false } tenant_ref = data.avi_tenant.admin.id cloud_ref = data.avi_cloud.default_cloud.id vrf_context_ref = data.avi_vrfcontext.vrf01.id } ★コマンド実行後 resource "avi_vsvip" "vip01" { name = "VIP_192.168.3.11" vip { vip_id = "0" ip_address { type = "V4" addr = "192.168.3.11" } auto_allocate_ip = false } tenant_ref = data.avi_tenant.admin.id cloud_ref = data.avi_cloud.default_cloud.id vrf_context_ref = data.avi_vrfcontext.vrf01.id }
私もTerraformを初めて1週間ですが、tfファイルの作成さえできてしまえば、コマンドの実行や切り戻しが非常に簡単で、かつコードの内容も理解がしやすいので、もっと早く身につけておけばよかったと思うほど便利です。
今回は、基本的なところの紹介でしたが、いろいろな製品でTerraformを利用していきたいと思います。
それでは、今回はこの辺で。