使用 Terraform 在 AWS 上设置 ScyllaDB 集群

在本文中,我演示了如何使用Terraform在AWS云中快速安装ScyllaDB的简单示例。

最初,我打算使用HashiCorp Packer创建ScyllaDB的AMI映像。但是,后来我发现官方映像是可用的,允许在实例初始化期间通过用户数据轻松配置ScyllaDB。

事实上,用户数据可以定义scylla.yaml中支持的所有参数。其他选项和示例可以在scylla-machine-image GitHub存储库中找到。

您还需要了解什么?要使ScyllaDB自动配置并启动,必须使用受支持的实例类型。可以在这里找到此类实例类型的列表:ScyllaDB在AWS上的系统要求。在我们的示例中,我们将使用i4i.large类型,因为它是受支持类型中最便宜的一种。

假设

  • 一个种子节点足以进行设置。
  • 主机可以从特定IP地址公开访问(需要静态公共IP)并受限访问。

Terraform配置示例

遵循最佳实践,Terraform代码分为单个目录中的多个文件。

变量文件(variables.tf)

Plain Text

 

variable "scylladb_version" {
  type        = string
  default     = "6.2.1"
  description = "The version of the ScyllaDB to install."
}

variable "your_public_network" {
  type        = string
  default     = "0.0.0.0/0"
  description = "Your public static IP address or your provider network."
}

variable "instance_type" {
  type        = string
  default     = "i4i.large"
  description = "The AWS instance type."
}

variable "number_of_regular_hosts" {
  type        = number
  default     = 2
  description = "The number of the regular (not seed) hosts in a cluster."
}

variable "ssh_key_name" {
  type        = string
  default     = "my_ssh_key"
  description = "The name of your public SSH key uploaded to AWS."
}

这个文件包含了在main.tf中包含的代码中使用的变量定义。我们稍后会讨论它们。

主配置文件(main.tf)

Plain Text

 

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# 配置 AWS 提供程序
provider "aws" {
  region = "eu-west-1"
}

variable "scylladb_version" {
  type        = string
  default     = "6.2.1"
  description = "The version of the ScyllaDB to install."
}

variable "your_public_network" {
  type        = string
  default     = "0.0.0.0/0"
  description = "Your public static IP address or your provider network."
}

variable "instance_type" {
  type        = string
  default     = "i4i.large"
  description = "The AWS instance type."
}

variable "number_of_regular_hosts" {
  type        = number
  default     = 2
  description = "The number of the regular (not seed) hosts in a cluster."
}

variable "ssh_key_name" {
  type        = string
  default     = "my_ssh_key"
  description = "The name of your public SSH key uploaded to AWS."
}

data "aws_ami" "scylladb_ami" {
  filter {
    name = "name"
    values = ["ScyllaDB ${var.scylladb_version}"]
  }
}

resource "aws_security_group" "scylladb_all" {
  name        = "scylladb_all"
  description = "Will allow all inbound traffic from your public IP"

  tags = {
    Name = "ScyllaDB"
  }
}

resource "aws_vpc_security_group_ingress_rule" "allow_all_inbound_traffic_ipv4" {
  security_group_id = aws_security_group.scylladb_all.id
  cidr_ipv4         = var.your_public_network
  ip_protocol       = "-1" # semantically equivalent to all ports
}

resource "aws_vpc_security_group_ingress_rule" "allow_all_internal_traffic_ipv4" {
  security_group_id            = aws_security_group.scylladb_all.id
  referenced_security_group_id = aws_security_group.scylladb_all.id
  ip_protocol                  = "-1" # semantically equivalent to all ports
}

resource "aws_vpc_security_group_egress_rule" "allow_all_traffic_ipv4" {
  security_group_id = aws_security_group.scylladb_all.id
  cidr_ipv4         = "0.0.0.0/0"
  ip_protocol       = "-1" # semantically equivalent to all ports
}

resource "aws_instance" "scylladb_seed" {
  ami           = data.aws_ami.scylladb_ami.id
  instance_type = var.instance_type
  vpc_security_group_ids = [aws_security_group.scylladb_all.id]
  key_name      = var.ssh_key_name

  user_data = <<EOF
scylla_yaml:
  cluster_name: test-cluster
  experimental: true
start_scylla_on_first_boot: true
EOF

  tags = {
    Name = "ScyllaDB seed"
  }
}

resource "aws_instance" "scylladb_host" {
  ami           = data.aws_ami.scylladb_ami.id
  instance_type = var.instance_type
  vpc_security_group_ids = [aws_security_group.scylladb_all.id]
  key_name      = var.ssh_key_name

  user_data = <<EOF
scylla_yaml:
  cluster_name: test-cluster
  experimental: true
  seed_provider:
    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
      parameters:
        - seeds: ${aws_instance.scylladb_seed.private_ip}
start_scylla_on_first_boot: true
EOF

  tags = {
    Name = "ScyllaDB host"
  }

  count = var.number_of_regular_hosts
}

main.tf文件描述了要创建的基础设施资源。

输出描述文件(outputs.tf)

Plain Text

 

output "scylladb_seed_public_ip" {
  value       = aws_instance.scylladb_seed.public_ip
  description = "Public IP address of the ScyllaDB seed host."
}

output "scylladb_host_public_ip" {
  value = [aws_instance.scylladb_host.*.public_ip]
  description = "Public IP addresses of ScyllaDB regular hosts."
}

该文件指定了最终要输出的数据。在我们的情况下,我们想要知道主机的 IP 地址,以便连接到它们。

您也可以在 GitHub 上找到这些代码:ScyllaDB Terraform 示例

如何使用此 Terraform 配置文件

首先,您需要安装 Terraform 和 AWS CLI。

Terraform 的安装在各个操作系统上有所不同。详细信息可以在官方文档中找到:Terraform 安装指南

AWS CLI 是一个 Python 模块,可以通过 pip 在所有支持 Python 的操作系统上以类似的方式安装。详细的安装说明可以在官方文档中找到:AWS CLI 在 PyPI 上

下一步是为 AWS CLI 设置安全凭据。安全凭据可以通过 AWS 的 IAM 服务创建。我们假定您已经拥有这些凭据。

要使AWS CLI以及随之的Terraform的AWS提供者能够使用您的凭据,您需要使用以下命令进行配置:

Shell

 

aws configure

还有其他传递凭据给Terraform的方法。更多详细信息可以在这里找到:AWS提供者身份验证

了解变量

以下是所有变量的详细说明:

  • scylladb_version:ScyllaDB的版本,在镜像名称中用于搜索AMI。
  • your_public_network:允许访问主机的外部IP地址。它应该采用CIDR格式(例如,/32代表单个地址)。
  • instance_type:AWS实例的类型。您必须使用上述推荐类型之一。
  • number_of_regular_hosts:群集中主机数量,不包括种子主机。
  • ssh_key_name:将添加到主机的预加载公共SSH密钥的名称。

尽管变量可以直接在variables.tf文件中重写,但最好使用单独的文件进行此操作。这可以是任何带有.tfvars扩展名的文件,例如terraform.tfvars,位于与Terraform配置文件相同的目录中。

在这样一个文件中,变量以<NAME> = <VALUE>的格式编写。例如:

Plain Text

 

ssh_key_name = "KEYNAME"

如何应用Terraform配置

要创建集群,请导航至包含代码的目录并运行以下命令:

初始化 AWS 提供者:

Shell

 

terraform init

示例输出:

Plain Text

 

Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.82.2...
- Installed hashicorp/aws v5.82.2 (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.

Terraform has been successfully initialized!

应用配置:

Shell

 

terraform apply

命令输出将显示一些参数取自提供给 Terraform 的配置,而其他参数将在应用更改后自动添加。确认应用程序,输入 yes。

当 Terraform 完成其工作时,它将输出主机的公共 IP 地址,您可以使用这些地址连接到 ScyllaDB。

验证集群部署

要验证 ScyllaDB 集群是否成功部署,请使用以下命令通过 SSH 连接到它:

Shell

 

ssh scyllaadm@<ip-address>

连接后,您将立即看到集群中的主机列表。或者,您可以运行以下命令:

Shell

 

nodetool status

示例输出:

Plain Text

 

Datacenter: eu-west
===================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- 地址       负载      令牌 拥有 主机 ID                              机架
UN 172.31.39.205 489.02 KB 256    ?    ac814131-bac5-488b-b7f8-b7201a8dbb23 1b  
UN 172.31.42.145 466.77 KB 256    ?    0bd8a16f-26d3-4665-878c-74b992b91a70 1b  
UN 172.31.46.42  526.42 KB 256    ?    3eb8966e-b42b-48c3-9938-7f24b1a6b097 1b  

所有主机的第一列必须显示 UN(正常运行)。

向集群添加主机

ScyllaDB 允许您轻松地向集群添加主机(但不能删除它们)。另外,Terraform 会保存上一次运行的状态并记住,例如,种子主机的 IP 地址。因此,您只需增加变量中的主机数量并再次运行 Terraform。新主机将自动加入集群。

将以下行添加到您的变量文件中:

Plain Text

 

number_of_regular_hosts = 3

在这个示例中,将向集群中再添加一个主机,但您可以将变量设置为大于2的任意数字。

再次运行terraform apply。然后,登录到种子主机并验证主机列表是否增加。

管理多个集群

您可以通过使用工作区在单个Terraform配置中部署多个集群。

创建一个新的工作区:

Shell

 

terraform workspace new cluster_2

cluster_2只是工作区的示例名称。它可以是任何名称。

部署新集群:

Shell

 

terraform apply

原始集群将保留在名为default的工作区中。

列出工作区:

Shell

 

terraform workspace list

在工作区之间切换:

Shell

 

terraform workspace select default

删除工作区:

Shell

 

terraform workspace delete cluster_2

销毁集群

要删除ScyllaDB集群和所有相关实体,请在所需的工作区中使用以下命令:

Shell

 

terraform destroy

这将清理Terraform为该集群创建的所有资源。

结论

通过本指南,您可以自信地在AWS上使用Terraform设置、管理和扩展ScyllaDB集群。提供的逐步说明确保无缝部署体验,让您专注于应用程序的性能和可伸缩性。

此外,Terraform 的灵活性使您能够轻松地根据需要调整和扩展集群,无论是添加新主机还是使用工作区管理多个集群。有关更多详细信息和高级配置,请参考 TerraformScyllaDB 的官方文档,这些文档提供了丰富的资源,帮助您最大化基础设施的潜力。

Source:
https://dzone.com/articles/setting-up-a-scylladb-cluster-on-aws-using-terraform