如今的开发团队越来越多地采用 DevOps 原则,例如持续集成和持续交付 (CI/CD)。因此,管理基础设施即代码 (IaC) 已成为任何云服务的必备能力。IaC 工具允许您使用配置文件而不是图形用户界面来管理基础设施。IaC 通过定义可版本控制、可复用和可共享的资源配置,使您能够以安全、一致和可重复的方式构建、更改和管理基础设施。
在 IaC 领域,HashiCorp Terraform 是领先的工具之一,它通过其提供商和模块支持主要的云提供商和服务,构建了一个云基础设施自动化生态系统,用于任何云、基础设施和服务的预置、合规性和管理。
Terraform 是一款开源的 IaC 软件工具,提供一致的 CLI 工作流程来管理数百种云服务。Terraform 将云 API 编码为声明性配置文件,这些文件可以在团队成员之间共享、视为代码、编辑、审查和版本化。它使您能够安全且可预测地创建、更改和改进基础设施。
Redis 开发了适用于 Redis Cloud 的 Terraform 提供商。HashiCorp Terraform Redis Cloud 提供商允许客户轻松地将 Redis Cloud 订阅、数据库和网络对等连接作为代码部署和管理,可在任何云提供商上进行。它是 Terraform 的一个插件,允许 Redis Cloud Flexible 客户管理其订阅和相关 Redis 数据库的完整生命周期。
Redis Cloud 提供商用于与 Redis Cloud 支持的资源进行交互。提供商在使用前需要配置正确的凭据。使用左侧导航可以了解可用的提供商资源和数据源。
在深入实施之前,让我们花点时间更好地理解 Terraform 配置。Terraform 配置是 Terraform 语言中的完整文档,它告诉 Terraform 如何管理一组给定的基础设施。一个配置可以包含多个文件和目录。Terraform 主要分为三个主要组件
提供商是 Terraform 配置文件中任何项目下需要定义的第一个资源。提供商允许您访问将用于创建资源的 API。一旦提供商配置和认证完成,即可创建大量资源。Terraform 支持超过 100 个云提供商。
提供商定义特定基础设施(例如 AWS)的资源和数据。如下所示,terraform 代码块 {} 包含 Terraform 设置,包括 Terraform 将用于预置基础设施所需的提供商(例如 rediscloud 提供商)。
terraform {
required_providers {
rediscloud = {
source = "RedisLabs/rediscloud"
version = "0.2.2"
}
}
}
provider {} 代码块配置特定的提供商。在下面的示例中,它是 AWS。
cloud_provider {
provider = "AWS"
cloud_account_id = 1
region {
region = "us-east-1"
networking_deployment_cidr = "10.0.0.0/24"
preferred_availability_zones = ["us-east-1a"]
}
}
资源是 Terraform 语言中最重要的元素。在这里,您描述要创建的基础设施片段,这可以从计算实例到定义特定权限等等。
如下所示,resource {} 代码块用于定义基础设施的组件。资源可以是物理或虚拟组件,例如 EC2,也可以是逻辑组件,例如 Heroku 应用。
resource "random_password" "passwords" {
count = 2
length = 20
upper = true
lower = true
number = true
}
resource {} 代码块在代码块之前有两个字符串:资源类型和资源名称。类型的名称前缀映射到提供商的名称。例如,资源类型“random_password”和资源名称“passwords”构成了资源的唯一标识符。Terraform 使用此 ID 来标识资源。
数据源允许 Terraform 使用在 Terraform 外部定义的信息、由另一个独立的 Terraform 配置定义的信息,或者由函数修改的信息。每个提供商除了其资源类型集之外,都可能提供数据源。数据源通过一种特殊类型的资源(称为数据资源)访问,使用 data 代码块声明。
data "rediscloud_payment_method" "card" {
card_type = "Visa"
last_four_numbers = "XXXX"
}
一个 data 代码块请求 Terraform 从给定的数据源(“rediscloud_payment_method”)读取数据,并以给定的本地名称(“card”)导出结果。该名称用于在同一 Terraform 模块的其他地方引用此资源,但在模块范围之外没有意义。
在代码块主体中(在 { 和 } 之间),是数据源定义的查询约束。本节中的大多数参数取决于数据源,并且在此示例中,card_type 和 last_four_numbers 都是专门为 rediscloud_payment_method 数据源定义的参数。
为了设置与 Redis Cloud 提供商的身份验证,必须为 Redis Cloud 生成编程 API 密钥。Redis Cloud 文档包含创建和管理您的密钥以及 IP 访问权限的最新说明。
灵活和年度 Redis Cloud 订阅可以利用 RESTful API,该 API 允许对各种资源进行操作,包括服务器、服务和相关基础设施。固定或免费订阅不支持 REST API。
provider "rediscloud" { } # Example resource configuration
resource "rediscloud_subscription" "example" { # ... }
如下所示,使用 Homebrew 在 MacOS 上安装 Terraform
brew install terraform
按照本教程 注册免费的 Redis Cloud 账户。
如果您拥有灵活(或年度)的 Redis Cloud 订阅,您可以使用 REST API 以编程方式管理您的订阅。Redis Cloud REST API 仅适用于灵活或年度订阅,不支持固定或免费订阅。
出于安全原因,Redis Cloud API 默认处于禁用状态。要启用 API,请执行以下步骤:
如果 API 账户密钥右侧出现“复制”按钮,则表示 API 已启用。此按钮会将账户密钥复制到剪贴板。
如果您看到“启用 API”按钮,请选择它来启用 API 并生成您的 API 账户密钥。
要认证 REST API 调用,您需要将 API 账户密钥与 API 用户密钥结合使用来发出 API 调用。
现在是时候创建一个空的“main.tf”文件,并开始添加提供商、资源和数据源,如下所示
terraform {
required_providers {
rediscloud = {
source = "RedisLabs/rediscloud"
version = "0.2.2"
}
}
}
# Provide your credit card details
data "rediscloud_payment_method" "card" {
card_type = "Visa"
last_four_numbers = "XXXX"
}
# Generates a random password for the database
resource "random_password" "passwords" {
count = 2
length = 20
upper = true
lower = true
number = true
special = false
}
resource "rediscloud_subscription" "rahul-test-terraform" {
name = "rahul-test-terraform"
payment_method_id = data.rediscloud_payment_method.card.id
memory_storage = "ram"
cloud_provider {
provider = "AWS"
cloud_account_id = 1
region {
region = "us-east-1"
networking_deployment_cidr = "10.0.0.0/24"
preferred_availability_zones = ["us-east-1a"]
}
}
database {
name = "db-json"
protocol = "redis"
memory_limit_in_gb = 1
replication = true
data_persistence = "aof-every-1-second"
module {
name = "RedisJSON"
}
throughput_measurement_by = "operations-per-second"
throughput_measurement_value = 10000
password = random_password.passwords[1].result
}
}
Terraform plan 命令会创建一个执行计划,让您预览 Terraform 计划对您的基础设施进行的更改。默认情况下,当 Terraform 创建计划时,它会读取任何已存在的远程对象的当前状态,以确保 Terraform 状态是最新的。然后,它会将当前配置与先前状态进行比较,并提出一组更改操作,以使远程对象与配置匹配。
% 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:
# random_password.passwords[0] will be created
+ resource "random_password" "passwords" {
+ id = (known after apply)
+ length = 20
+ lower = true
+ min_lower = 0
+ min_numeric = 0
+ min_special = 0
+ min_upper = 0
+ number = true
+ result = (sensitive value)
+ special = false
+ upper = true
}
# random_password.passwords[1] will be created
+ resource "random_password" "passwords" {
+ id = (known after apply)
+ length = 20
+ lower = true
+ min_lower = 0
+ min_numeric = 0
+ min_special = 0
+ min_upper = 0
+ number = true
+ result = (sensitive value)
+ special = false
+ upper = true
}
# rediscloud_subscription.rahul-test-terraform will be created
+ resource "rediscloud_subscription" "rahul-test-terraform" {
+ id = (known after apply)
+ memory_storage = "ram"
+ name = "rahul-test-terraform"
+ payment_method_id = "XXXX"
+ persistent_storage_encryption = true
+ cloud_provider {
+ cloud_account_id = "1"
+ provider = "AWS"
+ region {
+ multiple_availability_zones = false
+ networking_deployment_cidr = "10.0.0.0/24"
+ networks = (known after apply)
+ preferred_availability_zones = [
+ "us-east-1a",
]
+ region = "us-east-1"
}
}
+ database {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
}
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.
:::
Terraform apply 命令执行 Terraform 计划中提出的操作。
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:
# random_password.passwords[0] will be created
+ resource "random_password" "passwords" {
+ id = (known after apply)
+ length = 20
+ lower = true
+ min_lower = 0
+ min_numeric = 0
+ min_special = 0
+ min_upper = 0
+ number = true
+ result = (sensitive value)
+ special = false
+ upper = true
}
# random_password.passwords[1] will be created
+ resource "random_password" "passwords" {
+ id = (known after apply)
+ length = 20
+ lower = true
+ min_lower = 0
+ min_numeric = 0
+ min_special = 0
+ min_upper = 0
+ number = true
+ result = (sensitive value)
+ special = false
+ upper = true
}
# rediscloud_subscription.rahul-test-terraform will be created
+ resource "rediscloud_subscription" "rahul-test-terraform" {
+ id = (known after apply)
+ memory_storage = "ram"
+ name = "rahul-test-terraform"
+ payment_method_id = "XXXX"
+ persistent_storage_encryption = true
+ cloud_provider {
+ cloud_account_id = "1"
+ provider = "AWS"
+ region {
+ multiple_availability_zones = false
+ networking_deployment_cidr = "10.0.0.0/24"
+ networks = (known after apply)
+ preferred_availability_zones = [
+ "us-east-1a",
]
+ region = "us-east-1"
}
}
+ database {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
}
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
random_password.passwords[0]: Creating...
random_password.passwords[1]: Creating...
random_password.passwords[1]: Creation complete after 0s [id=none]
random_password.passwords[0]: Creation complete after 0s [id=none]
rediscloud_subscription.rahul-test-terraform: Creating...
rediscloud_subscription.rahul-test-terraform: Still creating... [10s elapsed]
rediscloud_subscription.rahul-test-terraform: Still creating... [20s elapsed]
rediscloud_subscription.rahul-test-terraform: Creation complete after 8m32s [id=1649277]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
您现在可以验证在名为“db-json”的订阅下创建的新数据库。
使用 Terraform 在 AWS 上部署带有 JSON 和 其他 Redis Stack 功能的 Redis 数据库
terraform {
required_providers {
rediscloud = {
source = "RedisLabs/rediscloud"
version = "0.2.2"
}
}
}
# Provide your credit card details
data "rediscloud_payment_method" "card" {
card_type = "Visa"
last_four_numbers = "XXXX"
}
# Generates a random password for the database
resource "random_password" "passwords" {
count = 2
length = 20
upper = true
lower = true
number = true
special = false
}
resource "rediscloud_subscription" "rahul-test-terraform" {
name = "rahul-test-terraform"
payment_method_id = data.rediscloud_payment_method.card.id
memory_storage = "ram"
cloud_provider {
provider = "AWS"
cloud_account_id = 1
region {
region = "us-east-1"
networking_deployment_cidr = "10.0.0.0/24"
preferred_availability_zones = ["us-east-1a"]
}
}
database {
name = "db-json"
protocol = "redis"
memory_limit_in_gb = 1
replication = true
data_persistence = "aof-every-1-second"
module {
name = "RedisJSON"
}
throughput_measurement_by = "operations-per-second"
throughput_measurement_value = 10000
password = random_password.passwords[1].result
}
}
Terraform destroy 命令是一种方便的方式,可以销毁由特定 Terraform 配置管理的所有远程对象。虽然您通常不希望在生产环境中销毁长期存在的对象,但 Terraform 有时用于管理开发目的的临时基础设施,在这种情况下,您可以使用 'terraform destroy' 在完成工作后方便地清理所有这些临时对象。
% terraform destroy
random_password.passwords[0]: Refreshing state... [id=none]
random_password.passwords[1]: Refreshing state... [id=none]
rediscloud_subscription.rahul-test-terraform: Refreshing state... [id=1649277]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# random_password.passwords[0] will be destroyed
- resource "random_password" "passwords" {
- id = "none" -> null
- length = 20 -> null
- lower = true -> null
- min_lower = 0 -> null
- min_numeric = 0 -> null
- min_special = 0 -> null
- min_upper = 0 -> null
- number = true -> null
- result = (sensitive value)
- special = false -> null
- upper = true -> null
}
# random_password.passwords[1] will be destroyed
- resource "random_password" "passwords" {
- id = "none" -> null
- length = 20 -> null
- lower = true -> null
- min_lower = 0 -> null
- min_numeric = 0 -> null
- min_special = 0 -> null
- min_upper = 0 -> null
- number = true -> null
- result = (sensitive value)
- special = false -> null
- upper = true -> null
}
# rediscloud_subscription.rahul-test-terraform will be destroyed
- resource "rediscloud_subscription" "rahul-test-terraform" {
- id = "1649277" -> null
- memory_storage = "ram" -> null
- name = "rahul-test-terraform" -> null
- payment_method_id = "XXXX" -> null
- persistent_storage_encryption = true -> null
- cloud_provider {
- cloud_account_id = "1" -> null
- provider = "AWS" -> null
- region {
- multiple_availability_zones = false -> null
- networking_deployment_cidr = "10.0.0.0/24" -> null
- networks = [
- {
- networking_deployment_cidr = "10.0.0.0/24"
- networking_subnet_id = "subnet-0055e8e3ee3ea796e"
- networking_vpc_id = ""
},
] -> null
- preferred_availability_zones = [
- "us-east-1a",
] -> null
- region = "us-east-1" -> null
}
}
- database {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
}
Plan: 0 to add, 0 to change, 3 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
rediscloud_subscription.rahul-test-terraform: Destroying... [id=1649277]
…
rediscloud_subscription.rahul-test-terraform: Destruction complete after 1m34s
random_password.passwords[0]: Destroying... [id=none]
random_password.passwords[1]: Destroying... [id=none]
random_password.passwords[0]: Destruction complete after 0s
random_password.passwords[1]: Destruction complete after 0s
Destroy complete! Resources: 3 destroyed.