如何使用 terraform 制作单 AZ(非 HA)RDS 实例?
How to make a single-AZ (non-HA) RDS instance with terraform?
在 this AWS 数据库博客中,他们断言
You can set up Amazon RDS in a Single-AZ database (DB) instance or a
Multi-AZ DB instance for high availability requirements
而且你可以
...modify existing Single-AZ instances to become Multi-AZ deployments.
此外,
...you can create a Multi-AZ read replica, synchronize it with your
Single-AZ DB instance, and then promote it as your primary DB instance
to minimize latencies during conversion.
另外,在官方AWS VPC Module there are multiple references to the usage of single_nat_gateway的v1.32中,特别是
If single_nat_gateway = true, then all private subnets will route
their Internet traffic through this single NAT gateway.
并且在官方 RDS 模块中,multi_az
默认显示为 false
(link)。
尽管如此,我还是收到以下错误
╷
│ Error: DBSubnetGroupDoesNotCoverEnoughAZs: The DB subnet group doesn't meet Availability Zone (AZ) coverage requirement. Current AZ coverage: us-west-2a. Add subnets to cover at least 2 AZs.
│ status code: 400, request id: *****
│
│ with module.rds.module.db_subnet_group.aws_db_subnet_group.this[0],
│ on .terraform/modules/rds/modules/db_subnet_group/main.tf line 8, in resource "aws_db_subnet_group" "this":
│ 8: resource "aws_db_subnet_group" "this" {
尝试terraform apply
此main.tf
配置时:
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "~> 3.4.0"
identifier = "${var.env}-${var.user}-${local.db_name}"
engine = var.postgres.engine
engine_version = var.postgres.engine_version
family = var.postgres.family
major_engine_version = var.postgres.major_engine_version
instance_class = var.postgres.instance_class
allocated_storage = var.postgres.allocated_storage
max_allocated_storage = var.postgres.max_allocated_storage
storage_encrypted = var.postgres.storage_encrypted
password = random_password.password.result
port = var.postgres.port
multi_az = false
subnet_ids = [data.aws_subnet.priv1.id]
vpc_security_group_ids = [module.db_security_group.security_group_id]
maintenance_window = var.postgres.maintenance_window
backup_window = var.postgres.backup_window
enabled_cloudwatch_logs_exports = var.postgres.enabled_cloudwatch_logs_exports
backup_retention_period = var.postgres.backup_retention_period
skip_final_snapshot = var.postgres.skip_final_snapshot
deletion_protection = var.postgres.deletion_protection
performance_insights_enabled = var.postgres.performance_insights_enabled
performance_insights_retention_period = var.postgres.performance_insights_retention_period
create_monitoring_role = var.postgres.create_monitoring_role
monitoring_role_name = "${var.env}-${var.user}-${var.postgres.monitoring_role_name}"
monitoring_interval = var.postgres.monitoring_interval
snapshot_identifier = var.postgres.snapshot_identifier
iam_database_authentication_enabled = var.postgres.iam_auth
apply_immediately = true
tags = {
Name = "${var.env}-${var.user}-rds"
Terraform = "true"
Environment = var.env
Created = timestamp()
}
}
在我的 terraform.tfvars
中定义了这个 postgres
变量:
postgres = {
db_name = "postgres-db"
# All available versions: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts
engine = "postgres"
engine_version = "11.12"
family = "postgres11" # DB parameter group
major_engine_version = "11" # DB option group
instance_class = "db.t2.micro"
allocated_storage = 100
max_allocated_storage = 200
storage_encrypted = false
port = 5432
multi_az = false
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"]
backup_retention_period = 0
skip_final_snapshot = true
deletion_protection = false
performance_insights_enabled = false
performance_insights_retention_period = 7
create_monitoring_role = true
monitoring_role_name = "monitoring_role"
monitoring_interval = 60
snapshot_identifier = "arn:aws:rds:us-west-2:999999999999:snapshot:rds-ss"
iam_auth = true
}
关于 SO 的类似问题似乎都有主题的答案,即您 必须 提供多个可用区,这意味着至少有两个子网,如果您手动创建它们作为私有子网 - 那么每个子网都需要自己的 NAT 网关。这似乎是不必要的昂贵和限制,特别是对于开发和测试环境。
如何使用这些组件部署单 az RDS Postgres 实例?
一个数据库子网组必须有多个子网。这是您无法绕过的 RDS 要求。即使您只部署一个实例,如果整个可用区都出现故障,Amazon RDS 也会自动在您指定的其他可用区之一中启动一个新实例。这是您通过 Amazon RDS 自动获得的托管数据库服务之一。
所以即使部署单az实例,也必须在DB子网组中指定多个可用区。
在 this AWS 数据库博客中,他们断言
You can set up Amazon RDS in a Single-AZ database (DB) instance or a Multi-AZ DB instance for high availability requirements
而且你可以
...modify existing Single-AZ instances to become Multi-AZ deployments.
此外,
...you can create a Multi-AZ read replica, synchronize it with your Single-AZ DB instance, and then promote it as your primary DB instance to minimize latencies during conversion.
另外,在官方AWS VPC Module there are multiple references to the usage of single_nat_gateway的v1.32中,特别是
If single_nat_gateway = true, then all private subnets will route their Internet traffic through this single NAT gateway.
并且在官方 RDS 模块中,multi_az
默认显示为 false
(link)。
尽管如此,我还是收到以下错误
╷
│ Error: DBSubnetGroupDoesNotCoverEnoughAZs: The DB subnet group doesn't meet Availability Zone (AZ) coverage requirement. Current AZ coverage: us-west-2a. Add subnets to cover at least 2 AZs.
│ status code: 400, request id: *****
│
│ with module.rds.module.db_subnet_group.aws_db_subnet_group.this[0],
│ on .terraform/modules/rds/modules/db_subnet_group/main.tf line 8, in resource "aws_db_subnet_group" "this":
│ 8: resource "aws_db_subnet_group" "this" {
尝试terraform apply
此main.tf
配置时:
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "~> 3.4.0"
identifier = "${var.env}-${var.user}-${local.db_name}"
engine = var.postgres.engine
engine_version = var.postgres.engine_version
family = var.postgres.family
major_engine_version = var.postgres.major_engine_version
instance_class = var.postgres.instance_class
allocated_storage = var.postgres.allocated_storage
max_allocated_storage = var.postgres.max_allocated_storage
storage_encrypted = var.postgres.storage_encrypted
password = random_password.password.result
port = var.postgres.port
multi_az = false
subnet_ids = [data.aws_subnet.priv1.id]
vpc_security_group_ids = [module.db_security_group.security_group_id]
maintenance_window = var.postgres.maintenance_window
backup_window = var.postgres.backup_window
enabled_cloudwatch_logs_exports = var.postgres.enabled_cloudwatch_logs_exports
backup_retention_period = var.postgres.backup_retention_period
skip_final_snapshot = var.postgres.skip_final_snapshot
deletion_protection = var.postgres.deletion_protection
performance_insights_enabled = var.postgres.performance_insights_enabled
performance_insights_retention_period = var.postgres.performance_insights_retention_period
create_monitoring_role = var.postgres.create_monitoring_role
monitoring_role_name = "${var.env}-${var.user}-${var.postgres.monitoring_role_name}"
monitoring_interval = var.postgres.monitoring_interval
snapshot_identifier = var.postgres.snapshot_identifier
iam_database_authentication_enabled = var.postgres.iam_auth
apply_immediately = true
tags = {
Name = "${var.env}-${var.user}-rds"
Terraform = "true"
Environment = var.env
Created = timestamp()
}
}
在我的 terraform.tfvars
中定义了这个 postgres
变量:
postgres = {
db_name = "postgres-db"
# All available versions: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts
engine = "postgres"
engine_version = "11.12"
family = "postgres11" # DB parameter group
major_engine_version = "11" # DB option group
instance_class = "db.t2.micro"
allocated_storage = 100
max_allocated_storage = 200
storage_encrypted = false
port = 5432
multi_az = false
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"]
backup_retention_period = 0
skip_final_snapshot = true
deletion_protection = false
performance_insights_enabled = false
performance_insights_retention_period = 7
create_monitoring_role = true
monitoring_role_name = "monitoring_role"
monitoring_interval = 60
snapshot_identifier = "arn:aws:rds:us-west-2:999999999999:snapshot:rds-ss"
iam_auth = true
}
关于 SO 的类似问题似乎都有主题的答案,即您 必须 提供多个可用区,这意味着至少有两个子网,如果您手动创建它们作为私有子网 - 那么每个子网都需要自己的 NAT 网关。这似乎是不必要的昂贵和限制,特别是对于开发和测试环境。
如何使用这些组件部署单 az RDS Postgres 实例?
一个数据库子网组必须有多个子网。这是您无法绕过的 RDS 要求。即使您只部署一个实例,如果整个可用区都出现故障,Amazon RDS 也会自动在您指定的其他可用区之一中启动一个新实例。这是您通过 Amazon RDS 自动获得的托管数据库服务之一。
所以即使部署单az实例,也必须在DB子网组中指定多个可用区。