iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
DevOps

大家都在用 Terraform 實作 IaC 為什麼不將程式寫得更簡潔易讀呢?系列 第 23

實作 AWS 常用服務之 Terraform 模組系列 - Launch an Custom AMI of Cassandra Cluster 篇

  • 分享至 

  • xImage
  •  

AWS Cassandra Cluster 模組實作

本篇是實作如何 launch Cassandra Cluster on AWS 之 Terraform 模組,完整的專案程式碼分享在我的 Github 上。

  1. 先定義模組 my_cassandra 的放置位置 modules/my_cassandra:
├── configs
│   ├── cloudfront
│   │   └── distributions.yaml
│   ├── cloudwatch
│   │   └── loggroups.yaml
│   ├── iam
│   │   ├── assume_role_policies
│   │   │   ├── eks-cluster.json
│   │   │   ├── eks-fargate-pod-execution-role.json
│   │   │   └── eks-node-group.json
│   │   ├── iam.yaml
│   │   ├── role_policies
│   │   │   └── eks-cluster-cloudwatch-metrics.json
│   │   └── user_policies
│   │       └── admin_access.json
│   ├── kinesis
│   │   └── streams.yaml
│   ├── kms
│   │   ├── keys.yaml
│   │   └── policies
│   │       └── my-key-policy.json
│   ├── s3
│   │   ├── policies
│   │   │   └── my-bucket.json
│   │   └── s3.yaml
│   ├── subnet
│   │   └── my-subnets.yaml
│   └── vpc
│       └── my-vpcs.yaml
├── example.tfvars
├── locals.tf
├── main.tf
├── modules
│   ├── my_cassandra
│   │   ├── aws_instance.cassandra.tf
│   │   ├── aws_security_groups.cassandra.tf
│   │   ├── data.aws_ami.ami.tf
│   │   ├── outputs.tf
│   │   ├── template
│   │   │   └── cassandra.yaml.tmpl
│   │   └── variables.tf
│   ├── my_cloudfront
│   ├── my_cloudwatch
│   ├── my_eips
│   ├── my_eventbridge
│   ├── my_iam
│   ├── my_igw
│   ├── my_instances
│   ├── my_kinesis_stream
│   ├── my_kms
│   ├── my_msk
│   ├── my_nacls
│   ├── my_route_tables
│   ├── my_s3
│   ├── my_subnets
│   └── my_vpc
├── my-ingress-controller-values.yaml
├── my-ingress-node-red.yaml
├── packer
│   └── apache-cassandra
│       ├── Makefile
│       ├── amazon-ebs.cassandra.pkr.hcl
│       ├── build.pkr.hcl
│       ├── example.pkrvars.hcl
│       ├── install-cassandra-exporter-standalone.sh
│       ├── install-cassandra-exporter.sh
│       ├── install-cassandra.sh
│       ├── install-cqlsh-standalone-tool.sh
│       ├── install-node-exporter.sh
│       ├── optimize-cassandra.sh
│       ├── values.auto.pkrvars.hcl
│       └── variables.pkr.hcl
└── variables.tf
  1. 撰寫 my_cassandra 模組:
  • ./modules/my_cassandra/outputs.tf:

output "instances" {
  value = aws_instance.cassandra
}

output "security_group" {
  value = aws_security_group.cassandra
}

  • ./modules/my_cassandra/provider.tf:
provider "aws" {
    region  = var.aws_region
    profile = var.aws_profile
}
  • ./modules/my_cassandra/variables.tf:
variable "aws_region" {
  description = "AWS region"
  default     = "ap-northeast-1"
}

variable "aws_profile" {
  description = "AWS profile"
  default     = ""
}

variable "project_name" {
  type    = string
  description = "Project name"
  default = ""
}

variable "department_name" {
  type        = string
  description = "Department name"
  default     = "SRE"
}

variable "instance_type" {
  description = "aws instance type and class"
  type        = string
}

variable "allowed_ranges" {
  description = "Allowed ranges that can access the cluster"
  type        = list(any)
  default     = ["0.0.0.0/0"]
}

variable "ssh-inbound-range" {
  description = "CIDRs of address that are allowed to ssh in."
  type        = list(any)
}

variable "subnet_ids" {
  description = "List of subnet Ids"
  type        = list(any)
}

variable "template-file" {
  type    = string
  default = "cassandra.tmpl"
}

variable "config-file" {
  type    = string
  default = "/etc/dse/cassandra/cassandra.yaml"
}

variable "ami" {
  description = "Contains information to select desired AWS AMI"
}

variable "vpc_id" {
  description = "The id for the vpc"
  type        = string
  validation {
    condition     = length(var.vpc_id) >= 12 && substr(var.vpc_id, 0, 4) == "vpc-"
    error_message = "The VPC ids need to start with vpc- and is at least 12 characters."
  }
}

variable "private_ips" {
  type        = list(any)
  description = "List of ips for the cassandra nodes"
}

variable "ssh_key_name" {
  description = "The ssh key name for the cassandra nodes"
  type        = string
}

variable "cluster_name" {
  description = "The cluster name for the cassandra nodes"
  type        = string
}

variable "root_password" {
  description = "The Cassandra root password"
  type        = string
}

variable "concurrent_reads" {
  description = "Should be set to (16 * number_of_drives) in order to allow the operations to enqueue low enough in the stack that the OS and drives can reorder them."
  type        = number
  default     = 32
}

variable "concurrent_writes" {
  description = "The ideal number of `concurrent_writes` is dependent on the number of cores in your system; (8 * number_of_cores) is a good rule of thumb."
  type        = number
  default     = 32
}

variable "concurrent_counter_writes" {
  description = "Same as `concurrent_reads`, since counter writes read the current values before incrementing and writing them back."
  type        = number
  default     = 32
}

variable "memtable_flush_writers" {
  description = "`memtable_flush_writers` defaults to two for a single data directory. This means that two  memtables can be flushed concurrently to the single data directory."
  type        = number
  default     = 2
}

variable "concurrent_compactors" {
  description = "`concurrent_compactors` defaults to the smaller of (number of disks, number of cores), with a minimum of 2 and a maximum of 8."
  type        = number
  default     = 8
}

variable "volume_size" {
  description = "The volume size (GB) for the cassandra nodes"
  type        = number
  default     = 100
}

  • ./modules/my_cassandraaws_instance.cassandra.tf: 其中利用 user_data 會把 Cassandra Config Template File 做變數取代後寫入 /etc/cassandra/conf/cassandra.yaml
variable "match_comment" { default = "/(?U)(?m)(?s)(^#.*$)/" }
resource "aws_instance" "cassandra" {
  count         = length(var.private_ips)
  ami           = data.aws_ami.ami.id
  instance_type = var.instance_type
  monitoring    = true
  private_ip    = var.private_ips[count.index]
  ebs_optimized = true
  key_name      = var.ssh_key_name

  root_block_device {
    volume_type           = "gp3"
    volume_size           = var.volume_size
    delete_on_termination = false
    encrypted             = false
  }

  vpc_security_group_ids = [aws_security_group.cassandra.id]
  subnet_id              = var.subnet_ids[count.index]

  lifecycle {
    create_before_destroy = true
  }

  metadata_options {
    http_endpoint = "enabled"
    http_tokens   = "required"
  }

  tags = {
    "Name"               = "Cassandra_ip-${replace(var.private_ips[count.index], "/\\./", "-")}"
    "Prometheus-monitor" = "enabled"
    "Application"        = "cassandra"
  }

  user_data = <<HERE
#!/bin/bash

read -d '' CONTENT << EOF
${replace(templatefile("${path.module}/template/cassandra.yaml.tmpl", {
  cluster_name              = "${var.cluster_name}",
  seeds                     = (length(var.private_ips) < 3) ? "${var.private_ips[0]}" : "${var.private_ips[0]},${var.private_ips[2]}",
  concurrent_reads          = "${var.concurrent_reads}",
  concurrent_writes         = "${var.concurrent_writes}",
  concurrent_counter_writes = "${var.concurrent_counter_writes}",
  memtable_flush_writers    = "${var.memtable_flush_writers}",
  listen_address            = "${var.private_ips[count.index]}",
  broadcast_rpc_address     = "${var.private_ips[count.index]}",
  concurrent_compactors     = "${var.concurrent_compactors}"
}), var.match_comment, "")}
EOF
echo "$CONTENT" > /etc/cassandra/conf/cassandra.yaml

TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" "http://169.254.169.254/latest/api/token")
LOCAL_IP=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/local-ipv4)
sed -i.bak "s/^# JVM_OPTS=\"\$JVM_OPTS -Djava.rmi.server.hostname=<public name>\"/JVM_OPTS=\"\$JVM_OPTS -Djava.rmi.server.hostname=$${LOCAL_IP}\"/" /etc/cassandra/conf/cassandra-env.sh
sed -i.bak "s/^    LOCAL_JMX=yes/    LOCAL_JMX=no/" /etc/cassandra/conf/cassandra-env.sh
sed -i.bak "s/^  JVM_OPTS=\"\$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=true\"/  JVM_OPTS=\"\$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=false\"/" /etc/cassandra/conf/cassandra-env.sh

systemctl enable cassandra
systemctl restart cassandra.service

echo "Waiting Cassandra to launch on 9042..."

while ! timeout 1 bash -c "echo > /dev/tcp/$${LOCAL_IP}/9042"; do
  sleep 1
done

sleep 15

if [ "$${LOCAL_IP}" = "${var.private_ips[0]}" ]; then
    /opt/cqlsh-astra/bin/cqlsh -u cassandra -p cassandra ${var.private_ips[0]} -e "ALTER USER cassandra WITH PASSWORD '${var.root_password}';"
fi

java -jar /opt/cassandra_exporter_standalone/cassandra-exporter-standalone.jar --cql-address $${LOCAL_IP}:9042 --cql-user=cassandra --cql-password=${var.root_password} &

HERE
}

  • ./modules/my_cassandra/aws_security_groups.cassandra.tf:
resource "aws_security_group" "cassandra" {
  #ts:skip=AC_AWS_0276 these rule has limit ip range, so skip the rule
  #ts:skip=AC_AWS_0239 these rule has limit ip range, so skip the rule
  name        = "Cassandra"
  description = "Cassandra security group managed by Terraform"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    description = "For SSH access"
    cidr_blocks = var.ssh-inbound-range
  }

  ingress {
    from_port   = 9042
    to_port     = 9042
    protocol    = "tcp"
    description = "CSQLSH port"
    cidr_blocks = var.allowed_ranges
  }

  ingress {
    from_port   = 9100
    to_port     = 9100
    protocol    = "tcp"
    description = "node-exporter 9100 port"
    cidr_blocks = var.allowed_ranges
  }

  ingress {
    from_port   = 9160
    to_port     = 9160
    protocol    = "tcp"
    description = "Cassandra Thrift port"
    cidr_blocks = var.allowed_ranges
  }

  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    description = "allow traffic for TCP 8080 (cassandra-exporter)"
    cidr_blocks = var.allowed_ranges
  }

  ingress {
    from_port   = 0
    to_port     = 65535
    protocol    = "tcp"
    description = "allows traffic from the SG itself for TCP"
    self        = true
  }

  ingress {
    from_port   = 7199
    to_port     = 7199
    protocol    = "tcp"
    description = "allow traffic for TCP 7199 (JMX)"
    cidr_blocks = var.allowed_ranges
  }

  ingress {
    from_port   = 7000
    to_port     = 7000
    protocol    = "tcp"
    description = "7000 Inter-node cluster"
    cidr_blocks = var.allowed_ranges
  }

  ingress {
    from_port   = 7001
    to_port     = 7001
    protocol    = "tcp"
    description = "Inter-node cluster SSL"
    cidr_blocks = var.allowed_ranges
  }

  ingress {
    from_port   = 9500
    to_port     = 9500
    protocol    = "tcp"
    description = "allow traffic for TCP 9500 (cassandra-exporter-standalone)"
    cidr_blocks = var.allowed_ranges
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    description = "Allow outbound"
    # tfsec:ignore:AWS009
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    "Name" = "Cassandra-SG"
  }

  vpc_id = var.vpc_id
}

  • ./modules/my_cassandra/data.aws_ami.ami.tf:
data "aws_ami" "ami" {
  most_recent = true

  filter {
    name   = "name"
    values = var.ami["filter"]
  }

  owners = var.ami["owners"]
}

  • ./modules/my_cassandra/template/cassandra.yaml.tmpl: Cassandra Config 設定檔案,由於檔案內容太長故省略,裡面可以將變數傳入做取代:
...
# any class that implements the SeedProvider interface and has a
# constructor that takes a Map<String, String> of parameters will do.
seed_provider:
    # Addresses of hosts that are deemed contact points.
    # Cassandra nodes use this list of hosts to find each other and learn
    # the topology of the ring.  You must change this if you are running
    # multiple nodes!
    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
      parameters:
          # seeds is actually a comma-delimited list of addresses.
          # Ex: "<ip1>,<ip2>,<ip3>"
          - seeds: "${seeds}"
...
  1. 撰寫專案相關程式
  • example.tfvars:
aws_region="ap-northeast-1"
aws_profile="<YOUR_PROFILE>"
project_name="example"
department_name="SRE"
cassandra_root_password="<CASSANDRA_ROOT_PASSWORD>"
  • locals.tf: 加入 cassandra_ami 篩選條件與 cassandra_private_ips launch Cassandra Cluster 機器的 IP 列表
locals {
  cassandra_ami = {
    filter = ["cassandra-BASE-v*-AMI-arm64"]
    owners = [data.aws_caller_identity.current.account_id]
  }

  cassandra_private_ips = [
    cidrhost("10.4.16.0/24", 248),
    cidrhost("10.4.17.0/24", 248),
    cidrhost("10.4.18.0/24", 248)
  ]
}

  • main.tf:
terraform {
  required_providers {
    aws = {
      version = "5.15.0"
    }
  }

  backend "s3" {
    bucket                  = "<YOUR_S3_BUCKET_NAME>"
    dynamodb_table          = "<YOUR_DYNAMODB_TABLE_NAME>"
    key                     = "terraform.tfstate"
    region                  = "ap-northeast-1"
    shared_credentials_file = "~/.aws/config"
    profile                 = "<YOUR_PROFILE>"
  }
}

其他模組省略...

# cassandra
module "cassandra" {
  instance_type = "t4g.medium"

  subnet_ids = [
    module.subnet.subnets["my-persistence-ap-northeast-1a"].id,
    module.subnet.subnets["my-persistence-ap-northeast-1c"].id,
    module.subnet.subnets["my-persistence-ap-northeast-1d"].id,
  ]

  #add the private ips
  private_ips       = local.cassandra_private_ips
  allowed_ranges    = ["10.4.0.0/16"]
  ssh-inbound-range = ["10.4.0.0/16"]
  ami               = local.cassandra_ami
  vpc_id            = module.vpc.my_vpcs["my-vpc"].id
  ssh_key_name      = var.ssh_key_name
  cluster_name      = "my-cassandra-dc1"
  root_password     = var.cassandra_root_password

  source = "./modules/my_cassandra"
}


Terraform 執行計畫

  1. 於專案目錄下執行 terraform init && terraform plan --out .plan -var-file=example.tfvars 來確認一下結果:

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:

  # module.cassandra.aws_instance.cassandra[0] will be created
  + resource "aws_instance" "cassandra" {
      + ami                                  = "ami-06737cc831127768d"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = true
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + host_resource_group_arn              = (known after apply)
      + iam_instance_profile                 = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_lifecycle                   = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t4g.medium"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = "my-ssh-key"
      + monitoring                           = true
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = "10.4.16.248"
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + spot_instance_request_id             = (known after apply)
      + subnet_id                            = "subnet-02edd71b69ad00233"
      + tags                                 = {
          + "Application"        = "cassandra"
          + "Name"               = "Cassandra_ip-10-4-16-248"
          + "Prometheus-monitor" = "enabled"
        }
      + tags_all                             = {
          + "Application"        = "cassandra"
          + "Name"               = "Cassandra_ip-10-4-16-248"
          + "Prometheus-monitor" = "enabled"
        }
      + tenancy                              = (known after apply)
      + user_data                            = "0e405fe8fea621e10f727a622383b94ed95e0930"
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = (known after apply)

      + metadata_options {
          + http_endpoint               = "enabled"
          + http_protocol_ipv6          = "disabled"
          + http_put_response_hop_limit = (known after apply)
          + http_tokens                 = "required"
          + instance_metadata_tags      = (known after apply)
        }

      + root_block_device {
          + delete_on_termination = false
          + device_name           = (known after apply)
          + encrypted             = false
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = 100
          + volume_type           = "gp3"
        }
    }

  # module.cassandra.aws_instance.cassandra[1] will be created
  + resource "aws_instance" "cassandra" {
      + ami                                  = "ami-06737cc831127768d"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = true
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + host_resource_group_arn              = (known after apply)
      + iam_instance_profile                 = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_lifecycle                   = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t4g.medium"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = "my-ssh-key"
      + monitoring                           = true
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = "10.4.17.248"
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + spot_instance_request_id             = (known after apply)
      + subnet_id                            = "subnet-0996848f084ff514f"
      + tags                                 = {
          + "Application"        = "cassandra"
          + "Name"               = "Cassandra_ip-10-4-17-248"
          + "Prometheus-monitor" = "enabled"
        }
      + tags_all                             = {
          + "Application"        = "cassandra"
          + "Name"               = "Cassandra_ip-10-4-17-248"
          + "Prometheus-monitor" = "enabled"
        }
      + tenancy                              = (known after apply)
      + user_data                            = "8d211558da9cf590e8e20ac44bbc42d6a19bf358"
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = (known after apply)

      + metadata_options {
          + http_endpoint               = "enabled"
          + http_protocol_ipv6          = "disabled"
          + http_put_response_hop_limit = (known after apply)
          + http_tokens                 = "required"
          + instance_metadata_tags      = (known after apply)
        }

      + root_block_device {
          + delete_on_termination = false
          + device_name           = (known after apply)
          + encrypted             = false
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = 100
          + volume_type           = "gp3"
        }
    }

  # module.cassandra.aws_instance.cassandra[2] will be created
  + resource "aws_instance" "cassandra" {
      + ami                                  = "ami-06737cc831127768d"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = true
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + host_resource_group_arn              = (known after apply)
      + iam_instance_profile                 = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_lifecycle                   = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t4g.medium"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = "my-ssh-key"
      + monitoring                           = true
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = "10.4.18.248"
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + spot_instance_request_id             = (known after apply)
      + subnet_id                            = "subnet-0f957e9f2d43009a7"
      + tags                                 = {
          + "Application"        = "cassandra"
          + "Name"               = "Cassandra_ip-10-4-18-248"
          + "Prometheus-monitor" = "enabled"
        }
      + tags_all                             = {
          + "Application"        = "cassandra"
          + "Name"               = "Cassandra_ip-10-4-18-248"
          + "Prometheus-monitor" = "enabled"
        }
      + tenancy                              = (known after apply)
      + user_data                            = "85c8839be6897443fa0914de97d2552f403807dc"
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = (known after apply)

      + metadata_options {
          + http_endpoint               = "enabled"
          + http_protocol_ipv6          = "disabled"
          + http_put_response_hop_limit = (known after apply)
          + http_tokens                 = "required"
          + instance_metadata_tags      = (known after apply)
        }

      + root_block_device {
          + delete_on_termination = false
          + device_name           = (known after apply)
          + encrypted             = false
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = 100
          + volume_type           = "gp3"
        }
    }

  # module.cassandra.aws_security_group.cassandra will be created
  + resource "aws_security_group" "cassandra" {
      + arn                    = (known after apply)
      + description            = "Cassandra security group managed by Terraform"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow outbound"
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "7000 Inter-node cluster"
              + from_port        = 7000
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 7000
            },
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "CSQLSH port"
              + from_port        = 9042
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 9042
            },
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "Cassandra Thrift port"
              + from_port        = 9160
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 9160
            },
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "For SSH access"
              + from_port        = 22
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 22
            },
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "Inter-node cluster SSL"
              + from_port        = 7001
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 7001
            },
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "allow traffic for TCP 7199 (JMX)"
              + from_port        = 7199
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 7199
            },
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "allow traffic for TCP 8080 (cassandra-exporter)"
              + from_port        = 8080
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 8080
            },
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "allow traffic for TCP 9500 (cassandra-exporter-standalone)"
              + from_port        = 9500
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 9500
            },
          + {
              + cidr_blocks      = [
                  + "10.4.0.0/16",
                ]
              + description      = "node-exporter 9100 port"
              + from_port        = 9100
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 9100
            },
          + {
              + cidr_blocks      = []
              + description      = "allows traffic from the SG itself for TCP"
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = true
              + to_port          = 65535
            },
        ]
      + name                   = "Cassandra"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags                   = {
          + "Name" = "Cassandra-SG"
        }
      + tags_all               = {
          + "Name" = "Cassandra-SG"
        }
      + vpc_id                 = "vpc-049f62a6dc464cb1c"
    }

Plan: 4 to add, 0 to change, 0 to destroy.
──────────────────────────────────────────────────────────────────────────────

Saved the plan to: .plan

To perform exactly these actions, run the following command to apply:
    terraform apply ".plan"

下一篇文章將會展示實作 AWS EKS with NodeGroup 之 Terraform 模組。


上一篇
實作 AWS 常用服務之 Terraform 模組系列 - Using Packer to Create an AMI 篇以建置 Cassandra Cluster 為例子
下一篇
實作 AWS 常用服務之 Terraform 模組系列 - EKS with Node Group 篇
系列文
大家都在用 Terraform 實作 IaC 為什麼不將程式寫得更簡潔易讀呢?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言