首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Terraform :由于修改而破坏后恢复数据?

Terraform :由于修改而破坏后恢复数据?
EN

Stack Overflow用户
提问于 2021-08-27 19:19:32
回答 1查看 1.5K关注 0票数 2

我正试图使用Terraform在AWS中创建一个RDS Aurora MySQL集群。但是,我注意到,每当我以需要替换它的方式更改集群时,所有数据都会丢失。我已配置为获取最后快照,并希望从该快照恢复,或通过替代措施恢复原始数据。

示例:更改群集-> TF将破坏原始群集-> TF,将其替换为原始群集->还原数据。

我尝试为aws_rds_cluster.snapshot_identifieraws_rds_cluster.final_snapshot_identifier使用相同的快照标识符,但是Terraform炸弹,因为销毁的集群的最后快照还不存在。

我也尝试过使用rds-finalsnapshot模块,但事实证明它主要用于上下旋转环境,保存数据。即销毁整个集群,然后将其重新创建为单独部署的一部分。(模块:https://registry.terraform.io/modules/connect-group/rds-finalsnapshot/aws/latest)

代码语言:javascript
复制
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的状态,然后应用?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-16 13:13:08

最终的解决方案相当简单,尽管很模糊。我尝试了50多种不同的方法,使用现有资源属性、提供程序、空资源(带有触发器)和外部数据块的组合,使用AWS CLI命令和Powershell脚本。

这里的挑战是,我需要确保按此顺序进行配置,以确保不丢失数据:

DMS复制任务阻止DMS复制任务将更多数据复制到数据库中。一旦传入的数据已为stopped.

  • Destroy并重新创建群集,

  • 将获取群集的新快照,并使用snapshot_identifier指定在上一步中拍摄的快照。

  • 破坏并重新创建DMS任务。

当然,这些步骤是基于Terraform如何决定需要应用更新的。它可能确定它只需要执行就地更新;这不是我所关心的。我需要处理资源被破坏的情况。

最后的解决方案是消除外部数据块的使用,而只使用本地提供程序,因为即使只运行terraform plan,外部数据块也会执行。我使用本地提供程序来访问诸如“创建”和“破坏”这样的生命周期事件,以确保我的Powershell脚本只在terraform apply期间执行。

在我的集群中,我将final_snapshot_identifiersnapshot_identifier设置为相同的值。

代码语言:javascript
复制
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的名字删除快照。

代码语言:javascript
复制
  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并获得一个全新的集群。所有后续部署都将使用最后的快照进行还原,并保留数据。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68958404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档