问题描述
在使用Terraform项目时遇到了一个问题,他希望在主要的”apply”过程中,能够延迟或分割项目,以避免MySQL Provider在AWS_RDS实例不存在时无法正确加载的问题。他已经尝试过使用工作区和计数来触发资源的加载或不加载,但并没有起作用。他在Hashicorp GitHub上也看到了这个问题的提及,但似乎没有人提供解决方法。他希望能得到帮助。
以下是他的数据存储配置的一部分示例:
resource "aws_db_subnet_group" "default" {
name = "${var.database_subnet_group_name}"
subnet_ids = ["${var.database_subnets}"]
tags {
Name = "${var.database_subnet_group_name}"
}
}
resource "aws_rds_cluster_instance" "cluster_instances" {
count = 1
identifier = "app-aurora-cluster-${count.index}"
cluster_identifier = "${aws_rds_cluster.some_cluster.id}"
instance_class = "db.t2.medium"
db_subnet_group_name = "${var.database_subnet_group_name}"
publicly_accessible = true
}
resource "aws_rds_cluster" "some_cluster" {
cluster_identifier = "app-aurora-cluster"
availability_zones = ["${var.database_azs}"]
database_name = "${var.database_name}"
db_subnet_group_name = "${var.database_subnet_group_name}"
master_username = "auroradmin"
master_password = "%XwPn}gU6sX<y8Wx"
skip_final_snapshot = true
vpc_security_group_ids = ["${var.database_security_groups}"]
}
/*# This has to be commented out during the first pass
# because Terraform will try to connect to the
# MySQL Aurora server to refresh the state even
# though it currently doesn't exist.
# Configure the MySQL provider
provider "mysql" {
endpoint = "${aws_rds_cluster.some_cluster.endpoint}"
username = "auroradmin"
password = "%XwPn}gU6sX<y8Wx"
}
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
你可以通过先对RDS资源运行Terraform,然后再对所有资源运行Terraform来实现类似的效果。
在第一次运行时,你可以使用-target
选项来仅针对一部分资源(即RDS资源)进行操作。
请注意,Terraform文档不推荐使用此选项。如果我是你,我会暂时使用它,并在以下任一问题解决后尽快更改:
– https://github.com/hashicorp/terraform/issues/10462
– https://github.com/hashicorp/terraform/issues/2430
– https://github.com/hashicorp/terraform/issues/4149
有关如何使用-target
及其注意事项的详细信息,请参阅:https://www.terraform.io/docs/commands/plan.html#resource-targeting
方案2
使用脚本或工具来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。
另一种方法是编写脚本或使用工具来控制容器的运行顺序。你可以使用docker run
命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。
示例:
以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:
#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b
在这个示例中,我们首先使用docker run
命令启动容器A,并将其命名为container_a
。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo
命令来测试)。一旦容器A就绪,我们再使用docker run
命令启动容器B,并将其命名为container_b
。