这是一个系列,记录了在不同的云厂商中使用Terraform的一些注意事项与常见的问题,以供参考。
目录
认证
概述
Oracle的认证相比其他云要稍微复杂一些,需要的认证信息包括:
- 租户ID:tenancy_ocid
- 用户ID:user_ocid
- API访问需要的秘钥对的私钥
- API访问需要的秘钥对的指纹(fingerprint)
这些信息可以参考:API Key Authentication@Configuring the Provider@Oracle Cloud Infrastructure Documentation。也注意到,在Oracle Cloud的文档中,有较为完整的Terraform文档,其目录为:Developer Resouces -> DevOps Tools and Plug-ins -> Terraform Provider
。
在Terraform中的认证
在Terraform中认证,有两种常见的形式,一种是在provider
提供完整的信息,如下:
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
}
也可以在Bash中使用全局变量:
export TF_VAR_tenancy_ocid="......"
export TF_VAR_user_ocid="......"
export TF_VAR_fingerprint="......"
export TF_VAR_private_key_path="......"
Compartment
概念
海外的云,各个都在“标新立异”…真的很烦。每个云都有着不同的概念,但是似乎都是去解决相同的问题,但实际上,又略有不同。这也许是这个世界是“多元”的又一体现… 我们来看看什么是Oracle Cloud中的Compartment
。
在官方文档Oracle Cloud Foundation
的Compartment
小结中有着详细的介绍:What is a Compartment?@Oracle Cloud Foundation。
文档的架构图,可视化的描述了tenancy
、region
、AD
、FD
和compartment
之间的关系。
Compartment
是一组逻辑资源的概念,可以方便的实现权限、账单管理tenancy
也是一个Compartment,并且是root Compartment
region
和其他云厂商一样是大地区的概念AD
则是一个大地区内的多个区(FD)组成的一个域FD
类似于其他云的zone
的概念
在Terraform中如何创建Compartment
完整的脚本和使用可以参考官方文档:。如下是一个简单的、经过验证的实现:
resource "oci_identity_compartment" "oic" {
#Required
compartment_id = var.tenancy_id
description = "for database benchmark"
name = var.naming
}
在控制台中切换不同的Compartment
初次使用OCI的用户来说,可能会遇到类似的问题,使用Terraform创建完资源后,在控制台中可能会找不到。这是因为,默认的控制台展示的tenancy(也就是root compartment)
下的资源,需要在侧栏List scope中切换到对应的Compartment
下。
一些问题汇总
问题:compartment_id” is required
│ Error: Missing required argument
│
│ on base.tf line 9, in resource "oci_core_vcn" "ocv":
│ 9: resource "oci_core_vcn" "ocv" {
│
│ The argument "compartment_id" is required, but no definition was found.
在创建第一个资源的时候,就遇到了这个问题。虽然在文档中,也看到了这个参数是Required的,不过感觉并没有必要。具体的参考本文的小结:compartment
。
问题:did not find a proper … private key
OCI的API使用需要使用秘钥对进行加/解密,对于秘钥对key有一定的要求,当使用一个自己生成的私钥对的时候,如果格式不兼容,是无法直接使用的。简单推荐的方式是,在OCI的控制台中生成一个秘钥对。
另外,主要秘钥对需要使用的PKCS#8
格式,如果使用了OpenSSH格式则也可能会报如下错误。
│ Error: can not create client, bad configuration: did not find a proper configuration for private key
│
│ with provider["registry.terraform.io/hashicorp/oci"],
│ on provider.tf line 10, in provider "oci":
│ 10: provider "oci" {
│
问题: 401-NotAuthenticated
这个问题的原因有很多,这里的是由于fingerprint
错误导致的。这里使用了某软件根据pem文件自动生成的fingerprint
,而这与Oracle Cloud格式的fingerprint
有所不同,plan
阶段不会宝座,apply
阶段则报如下错误,使用正确兼容格式(来自与Oracle Cloud控制台)的fingerprint
后,不再出现该报错。
│ Error: 401-NotAuthenticated, The required information to complete authentication was not provided or was incorrect.
│ Suggestion: Please retry or contact support for help with service: Identity Compartment
│ Documentation: https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_compartment
│ API Reference: https://docs.oracle.com/iaas/api/#/en/identity/20160918/Compartment/CreateCompartment
│ Provider version: 5.42.0, released on 2024-05-19.
│ Service: Identity Compartment
│ Operation Name: CreateCompartment
│ OPC request ID: ...
│
│
│ with oci_identity_compartment.oic,
│ on base.tf line 9, in resource "oci_identity_compartment" "oic":
│ 9: resource "oci_identity_compartment" "oic" {
│
默认资源
在Terraform中创建完VCN之后,Oracle会自动在VCN中自动创建一系列的默认资源,以减少手动操作,包括了:安全组、路由表(空)、dhcp options(参考:Managing Default VCN Resources)。所以,在Terraform再创建这些资源的时候,就可以利用原有的这些对象,进行管理。
具体的,可以先按如下方式创建VCN:
resource "oci_core_vcn" "ocv" {
#Required
compartment_id = oci_identity_compartment.oic.id
cidr_block = "172.17.0.0/16"
display_name = var.naming
}
这时,系统就自动化的创建了,对应的安全组、路由表等对象。这些对象的id,可以在oci_core_vcn.ocv
输出的default_security_list_id
、default_dhcp_options_id
、default_route_table_id
结果中获取。在Terraform脚本中,则需要三个专门的资源对象来管理,具体的:
oci_core_security_list
=>oci_core_default_security_list
oci_core_dhcp_options
=>oci_core_default_dhcp_options
oci_core_route_table
=>oci_core_default_route_table
例如,管理默认路由表:
resource "oci_core_default_route_table" "route_table_for_internet" {
manage_default_resource_id = oci_core_vcn.ocv.default_route_table_id
display_name = "RouteTableForInternet"
route_rules {
destination = "0.0.0.0/0"
destination_type = "CIDR_BLOCK"
network_entity_id = oci_core_internet_gateway.internet_gateway.id
}
}
完整的代码参考
那么初始化环境,并创建一个compartment
以及一个最简单的VCN,可以使用如下代码:
terraform {
required_providers {
oci = {
source = "hashicorp/oci"
version = ">= 4.0.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
}
resource "oci_identity_compartment" "oic" {
#Required
compartment_id = var.tenancy_id
description = "for database benchmark"
name = var.naming
}
resource "oci_core_vcn" "ocv" {
#Required
compartment_id = oci_identity_compartment.oic.id
cidr_block = "172.17.0.0/16"
display_name = var.naming
}
Leave a Reply