0.9.11。
data "aws_ecs_task_definition" "my-service" {
task_definition = "${aws_ecs_task_definition.my-service.family}"
}
resource "aws_ecs_task_definition" "my-service" {
family = "${var.environment_name}-${var.service_name}-${var.instance_name}"
network_mode = "bridge"
container_definitions = "${data.template_file.my-service.rendered}"
}
resource "aws_ecs_service" "my-service" {
...
#Track the latest ACTIVE revision
task_definition = "${aws_ecs_task_definition.my-services.family}:${max("${aws_ecs_task_definition.my-service.revision}", "${data.aws_ecs_task_definition.my-service.revision}")}"
...
}
如果资源不存在,请创建新的aws_ecs_task_definition,否则使用最新的aws_ecs_task_definition版本
这段代码在Terraform v0.9.2中很好用
:获取任务定义失败ClientException:无法描述任务定义。
状态码:400,请求ID:“ my-service”
terraform apply
也在terraform 1.0中复制
我也遇到了同样的问题! 令人好奇的是,当尝试使用香草状态(完全为空)进行搜索时,按预期计划和应用工作。 只有当我有一个现有的状态文件时,它才不起作用。
更奇怪的是,资源无论如何都不会存在于状态文件中,但是失败了吗? 🤔
深入调试...我注意到func dataSourceAwsEcsTaskDefinitionRead
在一个普通项目中不会被调用,而在现有项目中会被调用。 这似乎是一个地形图案。 通过首先创建一个简单的资源(一个安全组),然后尝试执行查找,我能够重现这一点。 当状态文件(在本例中为安全组)中已经存在资源时,该计划失败。 我还通过创建一个查找不存在的安全组的不同数据源来验证了我的假设。 该计划也失败了。
如果数据实例的参数不包含对计算值的引用,例如尚未创建的资源的属性,则将在Terraform的“刷新”阶段读取数据实例并更新其状态,该阶段默认情况下运行于制定计划。 这样可确保检索到的数据可在计划期间使用,并且差异将显示获得的实际值。
数据实例自变量可以引用计算值,在这种情况下,实例本身的属性只有在定义了其所有自变量之后才能被解析。 在这种情况下,刷新数据实例的时间将推迟到“应用”阶段,并且数据实例属性的所有插值将在计划中显示为“已计算”,因为尚不知道值。
这对我来说很有趣。 根据上述文档,OP的配置应该不会失败,因为data.aws_ecs_task_definition.my-service
取决于aws_ecs_task_definition.my-service.family
,但是它在计划*阶段失败了(我的问题也是)。 也许这是terraform级别的错误,而不是提供程序级别的错误?
@radeksimko我们能否引起您的注意? 如果不是主要问题,我不想向主存储库发送垃圾邮件。
我也看到了这个问题。
实际上,我不需要同一文件中的同一事物的数据和资源。 我注释掉了数据,现在看来效果更好。
通过向数据源添加“ depends_on”,我可以解决此问题:
resource "aws_ecs_task_definition" "task" {
...
}
data "aws_ecs_task_definition" "task" {
depends_on = [ "aws_ecs_task_definition.task" ]
...
}
希望能帮助到你。
这不是真正的错误, @ parruda的解决方案是正确的。 resource aws_ecs_service
和data aws_ecs_task_definition
都期望相关的resource aws_ecs_task_definition
必须已经创建。
@KIVagant很有意义,因为我也遇到了同样的问题。
尽管我会说该Terraform文档显示的data
对象和resource
一起使用应该进行更新以反映这一点。 从目前的情况来看,文档暗示如果资源不存在,那么任何事情都应该失败。
否则@parruda解决方案对我来说有意义
是的,我可能应该在回复之前尝试此修复程序,它可以工作,但是会引起连续更改检测。
这不是预期/期望的结果
@parruda的修复程序对我depends_on
会在每次tf运行时触发对我的任务定义的更新。 有防止这种情况的最佳做法吗? 我正在使用Terraform v0.11.5
和provider.aws v1.10.0。
@dendrochronology ,我使用这样的东西:
data "aws_ecs_task_definition" "blabla" {
task_definition = "${aws_ecs_task_definition.blabla.family}"
depends_on = [ "aws_ecs_task_definition.blabla" ]
}
resource "aws_ecs_task_definition" "..." {
family = "..."
task_role_arn = "${aws_iam_role.blabla.arn}"
container_definitions = "${data.template_file.task_definition.rendered}"
depends_on = [
"data.template_file.task_definition",
]
lifecycle {
ignore_changes = [
"container_definitions" # if template file changed, do nothing, believe that human's changes are source of truth
]
}
}
resource "aws_ecs_service" "blabla" {
name = "blabla"
cluster = "${aws_ecs_cluster.cluster_name.id}"
task_definition = "${aws_ecs_task_definition.blabla.family}:${max("${aws_ecs_task_definition.blabla.revision}", "${data.aws_ecs_task_definition.blabla.revision}")}"
desired_count = 1
iam_role = "${aws_iam_role.ecs_service.name}"
// Not compatible with placement_constraints:distinctInstance, commented
// placement_strategy {
// type = "binpack"
// field = "cpu"
// }
placement_constraints {
type = "distinctInstance"
}
load_balancer {
elb_name = "${aws_elb.blabla.name}"
container_name = "internal"
container_port = "${var.blabla_port}"
}
depends_on = [
"aws_iam_role.ecs_service",
"aws_elb.blabla",
"aws_iam_role.blabla",
"aws_ecs_task_definition.blabla"
]
lifecycle {
ignore_changes = ["task_definition"] # the same here, do nothing if it was already installed
}
}
@KIVagant ahhh,我将使用ignore_changes
生命周期挂钩!
啊,很好,我也会玩的。 这是否意味着我对任务定义模板文件进行更改时需要手动taint
?
这取决于您的目标。 在我们的例子中,模板包含用于秘密的空地方,这些地方在Terraform首次安装后就被填充,我们不想允许它更改现有的任务定义。 并且我们会在首次安装后手动控制它们。
@dendrochronology很抱歉缺乏回应。 实际上,我从来没有注意到这个问题,因为我们确实想在每次运行时都更新任务定义。 希望您找到了解决方案。
这似乎仍然是一个问题,如果仅使用文档中的内容,则会得到以下信息:
Error: Error running plan: 1 error(s) occurred:
* module.frontshop_staging.data.aws_ecs_task_definition.frontshop: 1 error(s) occurred:
* module.frontshop_staging.data.aws_ecs_task_definition.frontshop: Resource 'aws_ecs_task_definition.frontshop' not found for variable 'aws_ecs_task_definition.frontshop.family'
唯一更改的是它在模块内部,并且名称是frontshop。 可能与模块有关吗?
我也尝试了depends_on,它不起作用。 我正在考虑应用第一个版本来创建资源,然后将数据与max一起使用以获取最新版本。
实际上,我所说的是一个谎言,当您为容器定义使用无效的JSON时出现了问题,而我的方法不是使用Heredoc语法,而是使用带有模板的json文件,它应该是容器的数组,并且只有一个主要对象。
在这里我找到了关于它的地方https://github.com/terraform-providers/terraform-provider-aws/issues/2026
好一个@jaysonsantos。 就我而言,该错误是由于json语法错误而出现的
将提供程序升级到1.59和terraform 11.11后,我仍然看到此错误。
如果terraform destroy完全完成而没有错误,则可以正常运行,而无需depends_on。
但是,如果terraform destroy在其他方面失败,例如:
Error removing user, role, or group list from IAM Policy Detach bootstrap-iam-group-attach1:
– NoSuchEntity
与ecs服务无关。 以某种方式运行的地形再次被破坏会解决。 在第二遍
Failed getting task definition ClientException: Unable to describe task definition.
错误再次出现,状态文件损坏。
这个问题对我来说不是很清楚。 似乎有些人声称我们不应该在数据源中为任务定义使用depends_on,但是在第一次运行时,它总是会失败,因为该资源不存在。
仅供参考,其他人对此问题感到困惑: 了说明https://github.com/terraform-providers/terraform-provider-aws/pull/10247使用aws_ecs_task_definition.self.revision
的更好解决方法,并解释了为什么讨论的depends_on
方法不是您想要的!
这是在最初部署资源时没有任务定义的问题上解决的。 直接引用“ task_family”的文档示例不起作用,并且在最初应用它时退出并显示错误。 另请参阅此问题#1274
原因是,数据源无法正常处理丢失的数据。 不幸的是,如此处所述,将无法解决:hashicorp / terraform#16380(评论)。 建议的解决方法之一是添加一个显式
depends_on
。 但是,这将导致terraform计划输出可能发生变化,即使实际上并不会发生变化。 此外,Terraform文档本身并不鼓励这样做。该线程提到了其他一些解决方法,但是似乎都不适合使用hashicorp / terraform#16380
资源一旦创建,就只能引用
aws_ecs_task_definition.self.revision
(与代码中已经存在的family相对)。 显然,这使Terraform可以正确解决依赖关系并使数据源的行为符合预期。
最有用的评论
通过向数据源添加“ depends_on”,我可以解决此问题:
希望能帮助到你。