使用 Terraform 在 Oracle Cloud Infrastructure (OCI) 上部署 ARM 实例。





5.00/5 (1投票)
如何使用 Terraform 在 Oracle Cloud Infrastructure (OCI) 上部署 ARM 实例。
本文面向读者?
本文档是面向刚开始使用 Terraform 在 Oracle Cloud Infrastructure (OCI) 上部署 Arm 实例的软件开发人员的入门教程。
您将学到什么?
完成本学习路径后,您将能够
- 使用 Terraform 自动创建 OCI 上的 Arm 虚拟机
必备组件
开始之前,您需要准备以下内容
- 一个 OCI 账户
- 一台安装了 Terraform 的计算机
本学习路径使用 Terraform 自动创建 Oracle Cloud Infrastructure (OCI) 上的 Arm 虚拟机实例。
开始之前
在开始之前,您可能需要查看学习路径 《Oracle OCI 入门》。
任何安装了所需工具的计算机都可以使用。该计算机可以是您的台式机、笔记本电脑或装有必需工具的虚拟机。命令格式假定您正在 Linux 计算机上工作。
有关安装说明,请参阅 Terraform 安装指南。
您需要一个 Oracle OCI 账户 才能完成本学习路径。如果您还没有账户,请 创建账户 并使用 Oracle Cloud 免费套餐。
获取 OCI 访问凭证
要部署架构,您桌面或笔记本电脑上的 Terraform 会与 OCI 进行通信。为此,Terraform 需要进行身份验证。
为了进行身份验证,您需要生成密钥。Terraform 使用这些密钥以编程方式调用 OCI。
要生成和配置密钥,请按照以下步骤操作。
确认 Terraform 已安装
terraform -v
输出将类似于
Terraform v1.5.5
on linux_arm64
创建一个新目录来存储密钥文件
mkdir $HOME/.oci
生成私钥并调整权限
openssl genrsa -out $HOME/.oci/rsa_private.pem 2048
chmod 600 $HOME/.oci/rsa_private.pem
生成公钥
openssl rsa -pubout -in $HOME/.oci/rsa_private.pem -out $HOME/.oci/rsa_public.pem
显示公钥文件
cd $HOME/.oci
cat rsa_public.pem
复制公钥,包括第一行和最后一行,其中包含 ----BEGIN PUBLIC KEY----
和 ----END PUBLIC KEY---
在 OCI Web 控制台中,单击右上角的“配置文件”图标,然后从下拉菜单中选择您的配置文件。
单击页面左侧的 **API 密钥**,然后单击 **添加 API 密钥**。
选择 **粘贴公钥**,如下所示,然后将公钥内容粘贴到框中。请确保包含 ----BEGIN PUBLIC KEY----
和 ----END PUBLIC KEY---
您已将密钥与您的 OCI 账户关联。
准备您的基础设施即代码
Terraform 能够与同事共享您的代码,或公开共享,而不会暴露任何个人信息。
使用 Terraform,您还可以灵活地在不同区域、不同分区等位置部署相同的基础设施。因此,您应该创建通用文件来定义提供程序、分区、域,并使用一个包含通用文件中使用的变量值的文件。
您可以共享变量文件的模板,但要小心共享实际的变量值。
第一步是为您的代码创建一个目录
mkdir ~/arm-on-oci
cd ~/arm-on-oci
Terraform 提供程序
在此目录中,使用文本编辑器创建一个名为 _provider.tf_ 的文件,其中包含以下信息
provider "oci" {
tenancy_ocid = var.tenancy_ocid
region = var.region
user_ocid = var.user_ocid
fingerprint = var.fingerprint
private_key_path = var.private_key_path
}
您会注意到文件中没有实际数据,只有变量。当您想在 Oracle Cloud Infrastructure 上部署时,可以共享此文件。
Terraform 变量
您可以创建包含变量值的文件。
首先创建模板文件,以便在您想将基础设施或模块发布到 GitHub 等地方时与代码共享。
模板文件名为 _terraform.tfvars.template_。
使用文本编辑器创建 _terraform.tfvars.template_,并包含以下内容
# Oracle Cloud Infrastructure Authentication
tenancy_ocid = "ocid1.tenancy.<REPLACE_ME>"
user_ocid = "ocid1.user.oc1..<REPLACE_ME>"
fingerprint= "<REPLACE_ME>"
private_key_path = "<REPLACE_ME>.pem"
# Region
region = "<REPLACE_ME>" # example: eu-frankfurt-1
# Compartment
compartment_ocid = "ocid1.compartment.<REPLACE_ME>"
# Keys Configuration
ssh_authorized_keys_path = "<REPLACE_ME>.pub"
ssh_private_key_path = "<REPLACE_ME>"
该文件中不包含任何机密内容。
将文件复制到不应共享且将包含变量值的文件。该文件名为 _terraform.tfvars_。
cp terraform.tfvars.template terraform.tfvars
使用文本编辑器将每个字段替换为您 OCI 账户的值。您可以在 OCI 控制台的账户配置文件中找到租户信息 OCID 和用户 OCID。
私钥位于 _~/.oci/rsa_private.pem_
要获取私钥的密钥指纹,请运行 openssl
命令
openssl rsa -pubout -outform DER -in ~/.oci/rsa_private.pem | openssl md5 -c
注意
使用 OCI 文档 查找您的区域 。例如,区域可以是 us-ashburn-1
ssh_authorized_keys_path
和 ssh_private_key_path
的值定义了您将用于通过 SSH 连接到实例的 SSH 密钥的位置。
对于 ubuntu
用户名,它是
ssh_authorized_keys_path = "/home/ubuntu/.ssh/id_rsa.pub"
ssh_private_key_path = "/home/ubuntu/.ssh/id_rsa"
注意
如果您在 _~/.ssh_ 目录中没有 id_rsa
和 _id_rsa.pub_,请运行 ssh-keygen
生成新密钥。在提示时接受默认值,文件将被创建。
Terraform 还要求在专用文件中定义变量。
使用文本编辑器创建 _variables.tf_,并包含以下内容
variable "tenancy_ocid" {
description = "Tenancy's OCID"
}
variable "user_ocid" {
description = "User's OCID"
default = ""
}
variable "fingerprint" {
description = "Key Fingerprint"
default = ""
}
variable "private_key_path" {
description = "The private key path to pem."
default = ""
}
variable "region" {
description = "OCI Region"
}
variable "compartment_ocid" {
description = "Compartment's OCID where VCN will be created. "
}
variable "ssh_authorized_keys_path" {
description = "Public SSH keys path to be included in the ~/.ssh/authorized_keys file for the default user on the instance."
default = ""
}
variable "ssh_private_key_path" {
description = "The private key path to access instance."
default = ""
}
初始化 Terraform
初始化 Terraform 目录
terraform init
输出应类似于
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/oci...
- Installing hashicorp/oci v5.7.0...
- Installed hashicorp/oci v5.7.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.
╷
│ Warning: Additional provider information from registry
│
│ The remote registry returned warnings for registry.terraform.io/hashicorp/oci:
│ - For users on Terraform 0.13 or greater, this provider has moved to oracle/oci. Please update your source in required_providers.
╵
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_ 的目录,其中包含 OCI 提供程序的插件。
测试身份验证
要测试设置,您可以让 Terraform 执行一些操作。
首先,让 Terraform 显示所有可用域。
在同一目录中,创建一个名为 _availability-domains.tf_ 的文件,并包含以下内容
# Source from https://registry.terraform.io/providers/oracle/oci/latest/docs/data-sources/identity_availability_domains
# Tenancy is the root or parent to all compartments or if you have
# created one, you can use that one in the terraform.tfvars file.
data "oci_identity_availability_domains" "ads" {
compartment_id = var.tenancy_ocid
}
output "all-availability-domains-in-your-tenancy" {
value = data.oci_identity_availability_domains.ads.availability_domains
}
注意
确保 _provider.tf_ 和 _availability-domains.tf_ 在同一个目录中。Terraform 按正确的顺序处理目录中的所有文件。
Terraform Plan
运行 terraform plan
命令以打印可用域
terraform plan
输出将类似于
Changes to Outputs:
+ all-availability-domains-in-your-tenancy = [
+ {
+ compartment_id = "ocid1.tenancy.oc1..xxx"
+ id = "ocid1.availabilitydomain.xxx"
+ name = "QnsC:US-ASHBURN-AD-1"
},
+ {
+ compartment_id = "ocid1.tenancy.oc1..xxx"
+ id = "ocid1.availabilitydomain.xxx"
+ name = "QnsC:US-ASHBURN-AD-2"
},
+ {
+ compartment_id = "ocid1.tenancy.oc1..xxx"
+ id = "ocid1.availabilitydomain.xxx"
+ name = "QnsC:US-ASHBURN-AD-3"
},
]
You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.
Terraform Apply
运行 Terraform apply
命令将输出值保存到 Terraform 状态
terraform apply
当提示确认时,输入 yes
以创建您的资源。
运行 apply 命令后,输出将显示在终端中。
输出将类似于
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
all-availability-domains-in-your-tenancy = tolist([
{
"compartment_id" = "ocid1.tenancy.xxx"
"id" = "ocid1.availabilitydomain.xxx"
"name" = "QnsC:US-ASHBURN-AD-1"
},
{
"compartment_id" = "ocid1.tenancy.xxx"
"id" = "ocid1.availabilitydomain.xxx"
"name" = "QnsC:US-ASHBURN-AD-2"
},
{
"compartment_id" = "ocid1.tenancy.xxx"
"id" = "ocid1.availabilitydomain.xxx"
"name" = "QnsC:US-ASHBURN-AD-3"
},
])
您的 Oracle Cloud Infrastructure 账户现在已通过您的 Terraform 提供程序脚本进行身份验证。
注意
运行 apply
后再次尝试 plan
时,将不再看到输出。如果您先运行 terraform destroy
,则可以再次看到它。
创建 Ampere 计算实例
要创建您的第一个 Arm 计算实例,还需要其他几个资源
- 虚拟云网络 (VCN)
- 子网(公共)
- 互联网网关(访问互联网)
- 路由表(公共)
- 安全列表(公共)
您会注意到使用了 _public_。这意味着这些资源可以从公共互联网访问(它们可能分配有公共 IP 地址)。
在 OCI 中,某些服务仅在专用子网中可用,这些服务不能直接从互联网访问(例如 MySQL HeatWave Database Service)。
网络资源
首先,在名为 _network.tf_ 的专用 Terraform 文件中定义上面列出的所有资源
data "oci_identity_availability_domains" "ad" {
compartment_id = var.tenancy_ocid
}
resource "oci_core_virtual_network" "armvcn" {
cidr_block = "10.0.0.0/16"
compartment_id = var.compartment_ocid
display_name = "ampere_vcn"
dns_label = "armvcn"
}
resource "oci_core_internet_gateway" "internet_gateway_for_arm" {
compartment_id = var.compartment_ocid
display_name = "internet_gateway_for_arm"
vcn_id = oci_core_virtual_network.armvcn.id
}
resource "oci_core_route_table" "public_route_table" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_virtual_network.armvcn.id
display_name = "RouteTableForArmPublic"
route_rules {
destination = "0.0.0.0/0"
network_entity_id = oci_core_internet_gateway.internet_gateway_for_arm.id
}
}
resource "oci_core_security_list" "public_arm_security_list" {
compartment_id = var.compartment_ocid
display_name = "Allow Public SSH Connections to Ampere Compute Instance"
vcn_id = oci_core_virtual_network.armvcn.id
egress_security_rules {
destination = "0.0.0.0/0"
protocol = "6"
}
ingress_security_rules {
tcp_options {
max = 22
min = 22
}
protocol = "6"
source = "0.0.0.0/0"
}
}
resource "oci_core_subnet" "arm_public_subnet" {
cidr_block = "10.0.0.0/24"
display_name = "arm_public_subnet"
compartment_id = var.compartment_ocid
vcn_id = oci_core_virtual_network.armvcn.id
route_table_id = oci_core_route_table.public_route_table.id
security_list_ids = [oci_core_security_list.public_arm_security_list.id]
dns_label = "armpublic"
}
运行 Terraform plan
和 apply
以在 OCI 中创建资源
terraform plan ; terraform apply
在提示时回答 yes
。
输出确认已添加资源
...
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
可用区域列表将作为输出打印。您可以通过删除 _availability-domains.tf_ 文件来阻止这种情况发生。
创建 Arm (Ampere) 计算实例
是时候部署您的第一个基于 Arm 的 A1 计算实例了。
使用文本编辑器创建一个名为 _compute.tf_ 的文件
locals {
ssh_key = file(var.ssh_authorized_keys_path)
}
data "oci_core_images" "images_for_shape" {
compartment_id = var.compartment_ocid
operating_system = "Oracle Linux"
operating_system_version = "9"
shape = "VM.Standard.A1.Flex"
sort_by = "TIMECREATED"
sort_order = "DESC"
}
resource "oci_core_instance" "Ampere" {
compartment_id = var.compartment_ocid
display_name = "Always Free Ampere Compute"
availability_domain = data.oci_identity_availability_domains.ad.availability_domains[0].name
fault_domain = "FAULT-DOMAIN-1"
shape = "VM.Standard.A1.Flex"
dynamic "shape_config" {
for_each = [1]
content {
memory_in_gbs = 16
ocpus = 2
}
}
create_vnic_details {
subnet_id = oci_core_subnet.arm_public_subnet.id
display_name = "nic_arm_1"
assign_public_ip = true
hostname_label = "ampere1"
}
metadata = {
ssh_authorized_keys = local.ssh_key
}
source_details {
source_id = data.oci_core_images.images_for_shape.images[0].id
source_type = "image"
}
timeouts {
create = "10m"
}
}
运行 apply
命令以部署 Arm 计算实例
terraform apply
输出显示已添加 1 个资源
...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
在连接到新的计算实例之前,请更详细地查看 _compute.tf_ 文件
第 1 至 3 行:定义新的本地变量。本节仅包含一个保存已发布 SSH 密钥的变量。
第 5 至 12 行:指定与形状兼容的镜像。
要使用始终免费的 Ampere 形状,请使用 **VM.Standard.A1.Flex
**。
正如您所见,这些行按日期(降序)列出了与 Oracle Linux 9 兼容的形状。这意味着列表中的第一个元素将是最新镜像。
第 14 至 49 行:这是计算实例的定义。
第 21 至 27 行:定义实例的一些规范。对于 **Flex** 形状,您需要指定内存量和 OCPU。
第 29 至 34 行:创建一个虚拟网络接口卡,以连接到公共子网。
第 36 至 38 行:指定计算实例的元数据,即用于通过 SSH 连接的公钥 SSH。
第 40 至 43 行:要使用的镜像。使用列表中的第一个([0]
)。
第 45 至 47 行:指定实例创建的超时时间。
输出 IP 地址
与其使用 OCI 控制台查找 IP 地址,不如直接使用 Terraform 显示它更方便。
使用文本编辑器创建 _outputs.tf_ 文件
output "public_ip" {
value = oci_core_instance.Ampere.public_ip
}
运行 terraform refresh
以打印 IP 地址
terraform refresh
[...]
oci_core_instance.Ampere: Refreshing state... [id=ocid1.instance.oc1.iad.xxxxpgw2a]
Outputs:
public_ip = "1xx.xxx.xxx.x8"
使用 SSH 连接
现在您可以使用 SSH 连接到新的 Ampere 计算实例
将打印的 IP 地址替换到 SSH 命令中
ssh -i ~/.ssh/id_rsa opc@1xx.xxx.xxx.x8
您将以 ocp 用户登录,如下面的输出所示
The authenticity of host '1xx.xxx.xxx.x8 (1xx.xxx.xxx.x8)' can't be established.
ED25XXX key fingerprint is SHA256:wkFGCurGe+5AJtVmPIKCAqUKhw+xxxxxxxxxxxxxxxx.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '1xx.xxx.xxx.x8' (ED25XXX) to the list of known hosts.
[opc@ampere1 ~]$
使用 lscpu
命令验证 Arm 架构
lscpu
某些输出被省略,但您应该看到 aarch64
作为架构,Neoverse-N1
作为 CPU 模型名称
Architecture: aarch64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Vendor ID: ARM
Model name: Neoverse-N1
Model: 1
Thread(s) per core: 1
Core(s) per socket: 2
Socket(s): 1
Stepping: r3p1
BogoMIPS: 50.00
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asim
drdm lrcpc dcpop asimddp ssbs
您已使用 Terraform 在 OCI 中部署了第一个 Ampere 计算实例。
要删除资源,请运行
terraform destroy
想继续学习?访问 learn.arm.com 查找更多旨在帮助您更快地开发高质量 Arm 软件的教程。