为了加深对Terraform基础的理解,尝试构建Azure的存储账户
由于在工作中使用Terraform的机会增多,但对其中的一些部分仍然理解不够,为了加深理解,本次将通过使用Terraform构建Azure存储来总结学习。
Terraform 是什么?
-
- HashiCorp社によって開発されたインフラの設定をコードで管理するためのIaC(Infrastructure as Code)ツール
-
- HCL(HashiCorp Configration Language)という言語で定義を記述しインフラ構築をおこなうことができる
- AWSやMicrosoft Azure、Google Cloud Plattformなど様々なパブリッククラウドに対応
tfstate文件
这个文件用于记录Terraform所管理资源的当前配置。
在应用(apply)所定义的资源时,应用的配置将被记录。
文件的管理有以下两种方法。
-
- ローカル管理
特に保存先を指定していなければデフォルトでローカル環境のterraformを実行したカレントディレクトリにtfstateファイルが生成される
バックエンド管理
クラウドのストレージ上で管理をおこない開発メンバー間の共有ができる
バージョニング管理ができ、何かあった時の復旧が容易
我尝试使用Terraform构建Azure的存储账户。
前期准备
请根据以下教程参考方式,在Azure上安装Terraform并进行身份验证。
此外,根据以下内容,在存储中创建存储帐户和容器,以便能够管理tfstate文件。
创建配置文件
provider.tf 的中文释义是:供应者.tf。
首先,在terraform代码块中定义要使用的提供者。
这次我们将使用Azure存储来管理状态文件,因此在backend代码块中也会记录存储的信息。
terraform {
required_providers {
azurerm = {
version = ">=3.49.0"
}
}
backend "azurerm" {
resource_group_name = "backend_rg" # 事前準備で作成した resource-group-name
storage_account_name = "xxxxxtfbackend01" # 事前準備で作成した storage-account-name
container_name = "backend" # 事前準備で作成した container-name
key = "terraform.tfstate"
}
}
provider "azurerm" {
features {}
}
variables.tf的中文释义
接下来,我们会写下变量的定义。
variable "location" {
type = string
default = "japaneast"
}
variable "allow_nested_items_to_be_public" {
type = bool
default = false
}
variable "container_access_type" {
type = string
default = "private"
}
在type中定义变量的类型,在default中定义默认值。
定义的变量可以通过var.变量名进行引用。
主要.tf
我們將開始描述創建資源的定義。
本次將建立資源群組、存儲帳戶和存儲容器。
# リソースグループ
resource "azurerm_resource_group" "rg" {
name = "rg_strage"
location = var.location
}
# ストレージアカウント
resource "azurerm_storage_account" "sa" {
name = "xxxxxtf39demo01"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
allow_nested_items_to_be_public = var.allow_nested_items_to_be_public
}
# ストレージコンテナー
resource "azurerm_storage_container" "sc" {
name = "stragecon"
storage_account_name = azurerm_storage_account.sa.name
container_access_type = var.container_access_type
}
资源建设
初始化
执行init命令,进行工作目录的初始化和插件的下载。
$ terraform init
Initializing the backend...
Successfully configured the backend "azurerm"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding hashicorp/azurerm versions matching ">= 3.49.0"...
- Installing hashicorp/azurerm v3.53.0...
- Installed hashicorp/azurerm v3.53.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.
当Terraform初始化成功时,将显示消息:Terraform已成功初始化!您还可以使用-backend-config选项指定针对每个环境定义的后端。初始化后,将在本地生成以下目录和文件。
-
- .terraform
初期化時にキャッシュしたプロバイダーやモジュールなどの情報を格納するディレクトリ
.terraform.lock.hcl
初期化時にキャッシュしたプロバイダーやモジュールのバージョンの依存関係をロックするためのファイル
确认执行计划
因为初始化已经完成,所以在执行”plan”命令并应用之前,我们将确认执行计划。
$ 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:
# azurerm_resource_group.rg will be created
+ resource "azurerm_resource_group" "rg" {
+ id = (known after apply)
+ location = "japaneast"
+ name = "rg_strage"
}
# azurerm_storage_account.sa will be created
+ resource "azurerm_storage_account" "sa" {
+ access_tier = (known after apply)
+ account_kind = "StorageV2"
+ account_replication_type = "LRS"
+ account_tier = "Standard"
+ allow_nested_items_to_be_public = false
+ cross_tenant_replication_enabled = true
+ default_to_oauth_authentication = false
+ enable_https_traffic_only = true
+ id = (known after apply)
+ infrastructure_encryption_enabled = false
+ is_hns_enabled = false
+ large_file_share_enabled = (known after apply)
+ location = "japaneast"
+ min_tls_version = "TLS1_2"
+ name = "xxxxxtf39demo01"
+ nfsv3_enabled = false
+ primary_access_key = (sensitive value)
+ primary_blob_connection_string = (sensitive value)
+ primary_blob_endpoint = (known after apply)
+ primary_blob_host = (known after apply)
+ primary_connection_string = (sensitive value)
+ primary_dfs_endpoint = (known after apply)
+ primary_dfs_host = (known after apply)
+ primary_file_endpoint = (known after apply)
+ primary_file_host = (known after apply)
+ primary_location = (known after apply)
+ primary_queue_endpoint = (known after apply)
+ primary_queue_host = (known after apply)
+ primary_table_endpoint = (known after apply)
+ primary_table_host = (known after apply)
+ primary_web_endpoint = (known after apply)
+ primary_web_host = (known after apply)
+ public_network_access_enabled = true
+ queue_encryption_key_type = "Service"
+ resource_group_name = "rg_strage"
+ secondary_access_key = (sensitive value)
+ secondary_blob_connection_string = (sensitive value)
+ secondary_blob_endpoint = (known after apply)
+ secondary_blob_host = (known after apply)
+ secondary_connection_string = (sensitive value)
+ secondary_dfs_endpoint = (known after apply)
+ secondary_dfs_host = (known after apply)
+ secondary_file_endpoint = (known after apply)
+ secondary_file_host = (known after apply)
+ secondary_location = (known after apply)
+ secondary_queue_endpoint = (known after apply)
+ secondary_queue_host = (known after apply)
+ secondary_table_endpoint = (known after apply)
+ secondary_table_host = (known after apply)
+ secondary_web_endpoint = (known after apply)
+ secondary_web_host = (known after apply)
+ sftp_enabled = false
+ shared_access_key_enabled = true
+ table_encryption_key_type = "Service"
}
# azurerm_storage_container.sc will be created
+ resource "azurerm_storage_container" "sc" {
+ container_access_type = "private"
+ has_immutability_policy = (known after apply)
+ has_legal_hold = (known after apply)
+ id = (known after apply)
+ metadata = (known after apply)
+ name = "stragecon"
+ resource_manager_id = (known after apply)
+ storage_account_name = "xxxxxtf39demo01"
}
Plan: 3 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.
计划(Plan)命令会从tfstate文件中查看当前资源的状态,并显示添加、更改和删除资源的差异。执行命令成功后,将显示添加、更改和删除计划的摘要,例如:Plan 1 to add, 0 to change, 0 to destroy。
由于这是首次执行Terraform,尚未创建任何资源,因此将显示三个资源的计划摘要作为添加。
如果与当前资源状态对比后,没有需要添加或更改的资源,则会显示“No changes”。
执行apply命令后也是相同情况,但还有以下选项可用。
-var-fileオプションで.tfvarsの拡張子のファイルを指定して環境ごとの変数定義ファイルを指定することも可能
-targetオプションを使用して特定moduleのみ指定することも可能
适用条件
$ 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:
# azurerm_resource_group.rg will be created
+ resource "azurerm_resource_group" "rg" {
+ id = (known after apply)
+ location = "japaneast"
+ name = "rg_strage"
}
# azurerm_storage_account.sa will be created
+ resource "azurerm_storage_account" "sa" {
+ access_tier = (known after apply)
+ account_kind = "StorageV2"
+ account_replication_type = "LRS"
+ account_tier = "Standard"
+ allow_nested_items_to_be_public = false
+ cross_tenant_replication_enabled = true
+ default_to_oauth_authentication = false
+ enable_https_traffic_only = true
+ id = (known after apply)
+ infrastructure_encryption_enabled = false
+ is_hns_enabled = false
+ large_file_share_enabled = (known after apply)
+ location = "japaneast"
+ min_tls_version = "TLS1_2"
+ name = "xxxxxtf39demo01"
+ nfsv3_enabled = false
+ primary_access_key = (sensitive value)
+ primary_blob_connection_string = (sensitive value)
+ primary_blob_endpoint = (known after apply)
+ primary_blob_host = (known after apply)
+ primary_connection_string = (sensitive value)
+ primary_dfs_endpoint = (known after apply)
+ primary_dfs_host = (known after apply)
+ primary_file_endpoint = (known after apply)
+ primary_file_host = (known after apply)
+ primary_location = (known after apply)
+ primary_queue_endpoint = (known after apply)
+ primary_queue_host = (known after apply)
+ primary_table_endpoint = (known after apply)
+ primary_table_host = (known after apply)
+ primary_web_endpoint = (known after apply)
+ primary_web_host = (known after apply)
+ public_network_access_enabled = true
+ queue_encryption_key_type = "Service"
+ resource_group_name = "rg_strage"
+ secondary_access_key = (sensitive value)
+ secondary_blob_connection_string = (sensitive value)
+ secondary_blob_endpoint = (known after apply)
+ secondary_blob_host = (known after apply)
+ secondary_connection_string = (sensitive value)
+ secondary_dfs_endpoint = (known after apply)
+ secondary_dfs_host = (known after apply)
+ secondary_file_endpoint = (known after apply)
+ secondary_file_host = (known after apply)
+ secondary_location = (known after apply)
+ secondary_queue_endpoint = (known after apply)
+ secondary_queue_host = (known after apply)
+ secondary_table_endpoint = (known after apply)
+ secondary_table_host = (known after apply)
+ secondary_web_endpoint = (known after apply)
+ secondary_web_host = (known after apply)
+ sftp_enabled = false
+ shared_access_key_enabled = true
+ table_encryption_key_type = "Service"
}
# azurerm_storage_container.sc will be created
+ resource "azurerm_storage_container" "sc" {
+ container_access_type = "private"
+ has_immutability_policy = (known after apply)
+ has_legal_hold = (known after apply)
+ id = (known after apply)
+ metadata = (known after apply)
+ name = "stragecon"
+ resource_manager_id = (known after apply)
+ storage_account_name = "xxxxxtf39demo01"
}
Plan: 3 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
azurerm_resource_group.rg: Creating...
azurerm_resource_group.rg: Creation complete after 2s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_strage]
azurerm_storage_account.sa: Creating...
azurerm_storage_account.sa: Still creating... [10s elapsed]
azurerm_storage_account.sa: Still creating... [21s elapsed]
azurerm_storage_account.sa: Still creating... [31s elapsed]
azurerm_storage_account.sa: Still creating... [41s elapsed]
azurerm_storage_account.sa: Still creating... [51s elapsed]
azurerm_storage_account.sa: Still creating... [1m1s elapsed]
azurerm_storage_account.sa: Still creating... [1m11s elapsed]
azurerm_storage_account.sa: Creation complete after 1m19s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_strage/providers/Microsoft.Storage/storageAccounts/xxxxxtf39demo01]
azurerm_storage_container.sc: Creating...
azurerm_storage_container.sc: Creation complete after 0s [id=https://xxxxxtf39demo01.blob.core.windows.net/stragecon]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
apply命令是用于将定义的基础架构配置应用到云端的命令。
执行命令后会再次显示plan结果,在Enter a Value:处输入yes即可进行应用。
一旦apply完成,所应用资源的信息将会记录在terraform.tfstate文件中。
那么我们可以尝试重新执行plan命令以确认资源是否被应用成功。
terraform plan
azurerm_resource_group.rg: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_strage]
azurerm_storage_account.sa: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_strage/providers/Microsoft.Storage/storageAccounts/xxxxxtf39demo01]
azurerm_storage_container.sc: Refreshing state... [id=https://xxxxxtf39demo01.blob.core.windows.net/stragecon]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
没有变化。您的基础设施与配置相匹配。我已经确认了Azure门户上资源的创建。
由于可以添加资源,我们现在将在main.tf文件中添加另一个容器的资源定义并进行计划执行。
・・・
resource "azurerm_storage_container" "sc02" {
name = "stragecon02"
storage_account_name = azurerm_storage_account.sa.name
container_access_type = var.container_access_type
}
执行计划结果
$ terraform plan
azurerm_resource_group.rg: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_strage]
azurerm_storage_account.sa: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg_strage/providers/Microsoft.Storage/storageAccounts/xxxxxtf39demo01]
azurerm_storage_container.sc: Refreshing state... [id=https://xxxxxtf39demo01.blob.core.windows.net/stragecon]
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:
# azurerm_storage_container.sc02 will be created
+ resource "azurerm_storage_container" "sc02" {
+ container_access_type = "private"
+ has_immutability_policy = (known after apply)
+ has_legal_hold = (known after apply)
+ id = (known after apply)
+ metadata = (known after apply)
+ name = "stragecon02"
+ resource_manager_id = (known after apply)
+ storage_account_name = "xxxxxtf39demo01"
}
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.
由于之前应用的三个资源已记录在tfstate文件中,因此它们不会作为计划的差异显示。
而本次添加的容器会作为一个额外的差异显示。
整理其他主要的命令和代码块结构
命令
整理形式
$ terraform fmt
- Terraformの構成ファイルのインデントを揃えるためのフォーマットをおこなうコマンド
验证
$ terraform validate
-
- 定義した構文のチェックを行うコマンド
terraform planコマンドでもvalidateコマンドの機能が内包されている
摧毁
$ terraform destoroy
-
- Terraformで管理しているリソースの削除コマンド
terraform plan -destroyコマンドで削除対象のリソースの一覧を確認することも可能
陈述
$ terraform state list
- 作成したリソースの一覧を確認するためのコマンド
$ terraform state show リソース
- リソースを指定して作成したリソースの詳細を確認するためのコマンド
阻断
数据源
dataブロックで定義をおこない、Terraformの外部で定義された情報を参照するために使用
data "azurerm_storage_container" "sc" {
name = "stragecon"
storage_account_name = "xxxxxtf39demo01"
}
输出值
outputブロックで定義をおこない、リソースの情報を出力するために使用
applyコマンド実行すると出力される
data "azurerm_storage_container" "sc" {
name = "stragecon"
storage_account_name = "xxxxxtf39demo01"
}
output "azurerm_storage_container_access_type" {
value = data.azurerm_storage_container.sc.container_access_type
}
在执行apply命令后,container_access_type已被输出。
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
azurerm_storage_container_access_type = "private"
请参阅
最後
这次的构建非常简单,但是我们在实际使用Terraform构建时加深了对基础部分的理解。
今后我还想继续尝试各种不同的构建方式。