使用 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(Up Normal)。

將主機添加到集群

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為該集群創建的所有資源。

結論

通過本指南,您可以自信地使用Terraform在AWS上設置、管理和擴展ScyllaDB集群。提供的逐步指導確保了無縫的部署體驗,使您能專注於應用程序的性能和可擴展性。

此外,Terraform 的靈活性讓您能夠輕鬆地根據需要調整和擴展您的叢集,無論是新增主機還是管理多個工作區的叢集。如需進一步了解和進行高級配置,請參考 TerraformScyllaDB 的官方文檔,這些文檔提供豐富的資源,幫助您最大程度地發揮基礎設施的潛力。

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