最後更新: 2023-05-22
目錄
Install
yum install -y yum-utils
yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
yum -y install terraform # 會安 git, perl-Git
terraform -v
terraform -install-autocomplete # Install the TAB autocomplete package
# 它會在 .bashrc 加入
complete -C /usr/bin/terraform terraform
vim syntax highlighting
https://github.com/hashivim/vim-terraform
- yum install p7zip -y
- mkdir ~/.vim
- cd /usr/src
- wget https://github.com/hashivim/vim-terraform/zipball/master -O hashivim-`date +%Y%m%d`.zip
- 7za x hashivim-`date +%Y%m%d`.zip
- mv hashivim-vim-*/{autoload,ftdetect,ftplugin,indent,syntax} ~/.vim
Help
terraform -help init # Main commands: init, validate, plan, apply, destroy
Basic Usage
mkdir lab1; cd !$
建立 "main.tf"
terraform fmt # 格式好 main.tf
terraform init # 建建 provider 所而資料 (.terraform, .terraform.lock.hcl)
terraform validate # 要 init 後才可以 validate
# 匯出 AWS 登入資料
export AWS_ACCESS_KEY_ID=... export AWS_SECRET_ACCESS_KEY=...
P.S.
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
terraform plan # Preview 有什麼變動
terraform apply
terraform destroy # 刪除一切
說明
fmt
Rewrite Terraform configuration files to a canonical format and style.
執行後, 它會 Output 它修改過的檔案名
validate
Check whether the configuration is valid
init
initializes a "working directory" containing Terraform configuration files.
installs all providers and modules referred to in the Terraform project
upgrade the providers and modules for your project
terraform block does not include a cloud or backend block, Terraform defaults to the local backend.
validate
* 要 initialize 後才可以 validate config
使用情況: Update provider / module versions 時很有用
File & Directory 結構
lock file - .terraform.lock.hcl
The lock file ensures that Terraform uses the same provider versions across your team
.terraform directory
store the project's providers and modules.
terraform.tfstate
Terraform to map real world resources to your configuration, keep track of metadata
Terraform uses state to determine which changes to make to your infrastructure.
Prior to any operation, Terraform does a refresh to update the state with the real infrastructure.
CLI Configuration File
.terraformrc
# disables upgrade and security bulletin checks (會連到 HashiCorp)
disable_checkpoint = true
# disable the use of an anonymous signature in checkpoint requests
# (allow check for security bulletins)
disable_checkpoint_signature = true
Plugin cache
Enables plugin caching
mkdir /root/.terraform.d/plugin-cache
~/.terraformrc
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
By default, terraform init downloads plugins into a subdirectory of the working directory
so that each working directory is self-contained.
if you have multiple configurations that use the same provider
then a separate copy of its plugin will be downloaded for each configuration.
If the selected plugin is not already in the cache, Terraform will download it into the cache first and then
symbolic links under your current working directory
.terraform/providers/registry.terraform.io/hashicorp/aws/4.66.1 -> /root/.terraform.d/plugin-cache/registry.terraform.io/hashicorp/aws/4.66.1/linux_amd64
清垃圾
Over time, as plugins are upgraded, the cache directory may grow to contain several unused versions
which you must delete manually.
Cloud Provider AWS
Prerequisites
- Terraform CLI (1.2.0+)
- AWS CLI
-
AWS account and associated credentials that allow you to create resources.
(aws configure) - AWS plugin
AWS Plugin
/root/.terraform.d/plugin-cache/registry.terraform.io/hashicorp/aws
343M 4.66.1 346M 4.67.0
Step1: Login 到 AWS
除了 "export" login 外, 另外可以用其他方式 login
[1] Hard-coded
provider "aws" { access_key = "my-access-key" secret_key = "my-secret-key" }
* Hard-coded credentials are not recommended in any Terraform configuration
[2] Load awscli configure
provider "aws" { shared_config_files = ["/root/.aws/config"] shared_credentials_files = ["/root/.aws/credentials"] region = "ap-east-1" }
* 當沒有 export 及 Hard-Code 設定時, Default 會用 [~/.aws/config] 及 [~/.aws/credentials]
相當於
provider "aws" { region = "ap-east-1" }
Profile 設定
provider "aws" { shared_config_files = ["/root/.aws/config"] shared_credentials_files = ["/root/.aws/credentials"] profile = "customprofile" }
* If no named profile is specified, the default profile is used.
[default]
Step2: 準備 Project Folder 及 tf 檔
lab1.tf
// Comment
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.67.0" // providers 的版本
}
}
required_version = ">= 1.2.0" // terraform 的版本
}
provider "aws" {
region = "ap-east-1"
default_tags {
tags = {
Terraform = "true"
Environment = "Lab1"
}
}
}
/*
resource {...}
*/
Block
- terraform {} Terraform settings # 非必須
- provider{} Configures the specified provider # 必須
- resource {} Define components of your infrastructure (VPC, Instance ...)
terraform{}
當前最新機是 4.67.0
- version = "~> 4.66.0" // 符號 "~>" 表示只升級小版本號, 它只會安 4.66.1
- version = ">= 4.66.0" // 會直接安裝最新版
provider{}
- tags 是非必要的
AWS Provider Documentation
https://registry.terraform.io/providers/hashicorp/aws/latest
Good structure
在同一 Folder 內的 *.tf 檔都當作一個整體
- main.tf - call modules, locals, and data sources to create all resources
- variables.tf - declarations of variables used in main.tf
- outputs.tf - outputs from the resources created in main.tf
- terraform.tfvars - 存放 variables 的值
versions.tf
variable "cidr" { description = "The CIDR block for the VPC. Default value is a valid CIDR, but not acceptable by AWS and should be overriden" type = string default = "0.0.0.0/0" }
terraform.tfvars
cidr = "10.10.0.0/16"
*.tfvars
variable.tf are files where all variables are declared;
these might or might not have a default value.
variable.tfvars are files where the variables are provided/assigned a value.
main.tf
resource "aws_vpc" "this" { cidr_block = var.cidr }
outputs.tf
建議格式: {name}_{type}_{attribute}
outputs.tf
output "app_instance_id" { description = "ID of the EC2 instance" value = aws_instance.app_server.id } output "app_instance_public_ip" { description = "Public IP address of the EC2 instance" value = aws_instance.app_server.public_ip }
更新 outputs.tf 後要 "terraform apply" 才看到的 output
之後再想看就使用 "terraform output"
output - to extract the value of an output variable from the state file.
Inspect state
When you applied your configuration, Terraform wrote data into a file called terraform.tfstate
The Terraform state file is the only way Terraform can track which resources it manages,
and often contains sensitive information,
so you must store your state file securely and restrict access.
# human-readable output from a state or plan file
terraform show
Advanced state management (state)
terraform [global options] state <subcommand> [options] [args]
Subcommands:
list List resources in the state
mv Move an item in the state
pull Pull current state and output to stdout
push Update remote state from a local state file
replace-provider Replace provider in the state
rm Remove instances from the state
show Show a resource in the state
# list resources within a Terraform state
terraform state list
aws_internet_gateway.lab1-igw aws_route_table.lab1-rt aws_route_table_association.lab1-subnet-a aws_subnet.lab1-subnet-a aws_vpc.lab1-vpc
# show the attributes of a single resource in the state file that matches the given address.
terraform state show ADDRESS
i.e.
terraform state show aws_vpc.lab1-vpc
Destroy infrastructure
* It does not destroy resources running elsewhere that are not managed by the current Terraform project.
(This command is the inverse of "terraform apply")
terraform destroy