我正试图使用Terraform在AWS中创建一个RDS Aurora MySQL集群。但是,我注意到,每当我以需要替换它的方式更改集群时,所有数据都会丢失。我已配置为获取最后快照,并希望从该快照恢复,或通过替代措施恢复原始数据。
示例:更改群集-> TF将破坏原始群集-> TF,将其替换为原始群集->还原数据。
我尝试为aws_rds_cluster.snapshot_identifier和aws_rds_cluster.final_snapshot_identifier使用相同的快照标识符,但是Terraform炸弹,因为销毁的集群的最后快照还不存在。
我也尝试过使用rds-finalsnapshot模块,但事实证明它主要用于上下旋转环境,保存数据。即销毁整个集群,然后将其重新创建为单独部署的一部分。(模块:https://registry.terraform.io/modules/connect-group/rds-finalsnapshot/aws/latest)
module "snapshot_maintenance" {
source="connect-group/rds-finalsnapshot/aws//modules/rds_snapshot_maintenance"
identifier = local.cluster_identifier
is_cluster = true
database_endpoint = element(aws_rds_cluster_instance.cluster_instance.*.endpoint, 0)
number_of_snapshots_to_retain = 3
}
resource "aws_rds_cluster" "provisioned_cluster" {
cluster_identifier = module.snapshot_maintenance.identifier
engine = "aurora-mysql"
engine_version = "5.7.mysql_aurora.2.10.0"
port = 1234
database_name = "example"
master_username = "example"
master_password = "example"
iam_database_authentication_enabled = true
storage_encrypted = true
backup_retention_period = 2
db_subnet_group_name = "example"
skip_final_snapshot = false
final_snapshot_identifier = module.snapshot_maintenance.final_snapshot_identifier
snapshot_identifier = module.snapshot_maintenance.snapshot_to_restore
vpc_security_group_ids = ["example"]
}我所发现的是,如果一个更改需要破坏和更新,我没有一个很好的方法来恢复数据作为同一部署的一部分。
我要补充一点,我不认为这是我的代码的问题。更多的是TF的生命周期限制。我相信,在TF确定必须重新创建集群的情况下,我不能是唯一想要保存集群中数据的人。
如果我想防止由于对集群的更改导致破坏而丢失数据,是否需要在terraform之外或通过cli销毁群集,同步Terraform的状态,然后应用?
发布于 2021-09-16 13:13:08
最终的解决方案相当简单,尽管很模糊。我尝试了50多种不同的方法,使用现有资源属性、提供程序、空资源(带有触发器)和外部数据块的组合,使用AWS CLI命令和Powershell脚本。
这里的挑战是,我需要确保按此顺序进行配置,以确保不丢失数据:
DMS复制任务阻止DMS复制任务将更多数据复制到数据库中。一旦传入的数据已为stopped.
snapshot_identifier指定在上一步中拍摄的快照。
当然,这些步骤是基于Terraform如何决定需要应用更新的。它可能确定它只需要执行就地更新;这不是我所关心的。我需要处理资源被破坏的情况。
最后的解决方案是消除外部数据块的使用,而只使用本地提供程序,因为即使只运行terraform plan,外部数据块也会执行。我使用本地提供程序来访问诸如“创建”和“破坏”这样的生命周期事件,以确保我的Powershell脚本只在terraform apply期间执行。
在我的集群中,我将final_snapshot_identifier和snapshot_identifier设置为相同的值。
final_snapshot_identifier = local.snapshot_identifier
snapshot_identifier = data.external.check_for_first_run.result.isFirstRun == "true" ? null : local.snapshot_identifier只有在第一次部署之后才设置snapshot_identifier,外部数据块允许我检查资源是否已经存在,以便达到这个条件。这个条件是必要的,因为在第一次部署时,快照将不存在,Terraform在“计划”步骤中会因此而失败。
然后,我在本地提供程序中执行一个Powershell脚本来停止任何DMS任务,然后以local.snapshot_identifier的名字删除快照。
provisioner "local-exec" {
when = destroy
# First, stop the inflow of data to the cluster by stopping the dms tasks.
# Next, we've tricked TF into thinking the snapshot we want to use is there by using the same name for old and new snapshots, but before we destroy the cluster, we need to delete the original.
# Then TF will create the final snapshot immediately following the execution of the below script and it will be used to restore the cluster since we've set it as snapshot_identifier.
command = "/powershell_scripts/stop_dms_tasks.ps1; aws rds delete-db-cluster-snapshot --db-cluster-snapshot-identifier benefitsystem-cluster"
interpreter = ["PowerShell"]
}这将清除最后一个快照,并允许Terraform以与原始快照相同的名称创建新的最终快照,以便及时用于还原。
现在,我可以第一次运行Terraform并获得一个全新的集群。所有后续部署都将使用最后的快照进行还原,并保留数据。
https://stackoverflow.com/questions/68958404
复制相似问题