3. Terraform on OCI快速上手
本节把 Terraform 从“听说过”推进到“能在 OCI 上真正跑起来”。目标很明确:在本地安装 Terraform,配置 OCI Provider 的认证信息,用 HCL 写出一个虚拟云网络(VCN)和一台计算实例,执行 terraform apply 后能在 OCI 控制台看到资源,最后用 terraform destroy 清理干净。整个过程围绕三个核心对象展开:Terraform CLI、OCI Provider、以及由 VCN 与计算实例组成的最小资源栈。
一、安装 Terraform 与准备 OCI 认证
Terraform 是单个二进制文件,安装方式取决于操作系统。以 Linux/macOS 为例,推荐使用 HashiCorp 官方仓库或直接下载压缩包。安装完成后用版本命令确认:
# 以 Linux x86_64 为例,下载并解压到 PATH
wget https://releases.hashicorp.com/terraform/1.9.5/terraform_1.9.5_linux_amd64.zip
unzip terraform_1.9.5_linux_amd64.zip -d /usr/local/bin/
terraform -version
# 预期输出:Terraform v1.9.5
OCI Provider 需要认证信息才能调用 OCI API。最常用的方式是 API Key 认证,需要准备四类信息:tenancy OCID、user OCID、fingerprint、private key 文件路径。这些信息来自 OCI 控制台“用户设置 → API 密钥”中生成的密钥对。把公钥上传到 OCI 后,控制台会给出 fingerprint,私钥保存在本地,例如 ~/.oci/oci_api_key.pem。此外还需要 region,例如 ap-singapore-1。
.tf 文件提交到 Git。推荐使用环境变量或 ~/.oci/config 文件,Terraform 会自动读取。二、Provider 配置与变量组织
新建一个工作目录,例如 oci-demo,在其中创建 provider.tf。Provider 块声明使用 oracle/oci,并指定版本约束,避免不同环境拉到不兼容版本:
terraform {
required_providers {
oci = {
source = "oracle/oci"
version = "~> 6.0"
}
}
}
provider "oci" {
tenancy_ocid = var.tenancy_ocid
user_ocid = var.user_ocid
fingerprint = var.fingerprint
private_key_path = var.private_key_path
region = var.region
}
把易变参数抽到 variables.tf,例如 compartment_ocid、region、ssh_public_key。这样同一份代码可以在不同 compartment 或 region 复用。变量值可以写在 terraform.tfvars 中,但该文件同样不应提交敏感内容。
三、编写 VCN 与计算实例资源定义
VCN 是 OCI 中的软件定义网络,计算实例必须落在某个子网中。最小可用网络需要:VCN、Internet Gateway、路由表、子网。下面用 network.tf 定义这些资源,CIDR 使用示例值 10.0.0.0/16,子网使用 10.0.1.0/24:
resource "oci_core_vcn" "demo_vcn" {
compartment_id = var.compartment_ocid
cidr_block = "10.0.0.0/16"
display_name = "demo-vcn"
dns_label = "demovcn"
}
resource "oci_core_internet_gateway" "demo_igw" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.demo_vcn.id
display_name = "demo-igw"
enabled = true
}
resource "oci_core_route_table" "demo_rt" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.demo_vcn.id
display_name = "demo-rt"
route_rules {
destination = "0.0.0.0/0"
network_entity_id = oci_core_internet_gateway.demo_igw.id
}
}
resource "oci_core_subnet" "demo_subnet" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.demo_vcn.id
cidr_block = "10.0.1.0/24"
display_name = "demo-subnet"
dns_label = "demosub"
route_table_id = oci_core_route_table.demo_rt.id
security_list_ids = [oci_core_vcn.demo_vcn.default_security_list_id]
}
接着在 compute.tf 中定义计算实例。需要指定可用域、shape、镜像、子网和 SSH 公钥。镜像通过数据源查询最新 Oracle Linux 8:
data "oci_core_images" "ol8" {
compartment_id = var.compartment_ocid
operating_system = "Oracle Linux"
operating_system_version = "8"
shape = "VM.Standard.E4.Flex"
sort_by = "TIMECREATED"
sort_order = "DESC"
}
resource "oci_core_instance" "demo_vm" {
compartment_id = var.compartment_ocid
availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
shape = "VM.Standard.E4.Flex"
display_name = "demo-vm"
shape_config {
ocpus = 1
memory_in_gbs = 8
}
source_details {
source_type = "image"
source_id = data.oci_core_images.ol8.images[0].id
}
create_vnic_details {
subnet_id = oci_core_subnet.demo_subnet.id
assign_public_ip = true
}
metadata = {
ssh_authorized_keys = var.ssh_public_key
}
}
注意 availability_domain 需要先通过 data "oci_identity_availability_domains" 查询,否则无法确定具体 AD 名称。这是初学者最容易漏掉的一步。
四、初始化、计划与部署
资源定义写完后,执行标准三步。第一步初始化,下载 Provider 插件并生成锁文件:
terraform init
# 输出中会看到 Installing oracle/oci v6.x.x...
第二步用 plan 预览将要创建的资源。这一步不会真正调用创建接口,但会读取现有状态并计算差异。重点关注输出末尾的 Plan: 5 to add, 0 to change, 0 to destroy,确认数量与预期一致:
terraform plan -out=tfplan
# Plan: 5 to add, 0 to change, 0 to destroy.
第三步应用。使用 -out 保存的计划文件可以保证 apply 的内容与 plan 完全一致:
terraform apply tfplan
# Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
# Outputs:
# public_ip = "203.0.113.45"
部署完成后,在 OCI 控制台进入对应 compartment,可以看到 demo-vcn、demo-subnet、demo-vm 等资源。用输出的公网 IP 尝试 SSH:
ssh opc@203.0.113.45
# 登录成功即说明网络路由、安全列表和实例均正常
五、结果判断与清理
判断部署是否成功,可以看三个层面:Terraform 输出是否显示 Apply complete;OCI 控制台资源列表是否出现对应 display_name;SSH 是否能连通。如果 SSH 超时,优先检查子网是否关联了正确的路由表、安全列表是否放行 22 端口、实例是否分配了公网 IP。这三个点覆盖了绝大多数首次部署失败的原因。
terraform destroy,否则计算实例会持续计费。destroy 会依据 state 文件逆序删除资源,VCN 和子网也会一并清理。terraform destroy
# Destroy complete! Resources: 5 destroyed.