1

terraform applyモジュールで使用する場合、段階的に循環依存の問題に苦しんでdepends_onいます。

適用で得たエラーは次のとおりです。

* Cycle: aws_appautoscaling_policy.queue_depth_based_scale_out_policy, module.my_module.aws_ecs_task_definition.task_definition (destroy), aws_appautoscaling_policy.queue_depth_based_scale_in_policy

planステージはまったく問題なく、ステージにエラーはありませんplan

以下のコマンドを使用してグラフ内のサイクルを特定しようとしましたが、

terraform graph -draw-cycles -module-depth=0 -type=plan  | dot -Tsvg > graph-plan.svg

planグラフにサイクルはありません。次に、使用中のサイクルを特定しようとしましたがapply

terraform graph -draw-cycles -module-depth=0 -type=apply  | dot -Tsvg > graph-apply.svg

残念ながら、このコマンドはサイクルをグラフに表示できません。

幸いなことに、apply以下のコマンドを使用してステージ グラフでサイクルを確認できます。

terraform plan -out tfplan
terraform graph -draw-cycles -module-depth=0 tfplan | dot -Tsvg > graph-apply.svg

私のグラフのサイクルは次のようになります。

適用段階のサイクルを示すグラフ

とはいえ、グラフのこのサイクルの理由はまだわかりません。

さらに、問題は特にdepends_onモジュールの追加にあるようです。aws_appautoscaling_policy私のモジュールにはすでに依存しているものはほとんどないので、依存するaws_appautoscaling_targetものは依存しaws_ecs_service、最終的には依存しますaws_ecs_task_definitionapply、これは正常に機能します。

aws_appautoscaling_policy特定のアプリに特に関連するものもあるため、個別に (モジュールの一部としてではなく) 追加していますが、自動スケーリング ポリシーは、サービスがスケーラブル ターゲットとして登録された後にのみ追加できるため、モジュールを追加しdepends_onています。aws_appautoscaling_targetモジュールで定義されているので。

モジュールのコードスニペットは次のとおりです。

resource "aws_ecs_task_definition" "task_definition" {
  family                = "${var.service_name}"
  container_definitions = "${var.container_definitions}"
  task_role_arn         = "${aws_iam_role.task_role.arn}"
  lifecycle {
    create_before_destroy = true
  }
}
resource "aws_ecs_service" "service" {
  name                               = "${var.service_name}"
  cluster                            = "${data.aws_ecs_cluster.ecs_cluster.arn}"
  task_definition                    = "${aws_ecs_task_definition.task_definition.arn}"
  deployment_minimum_healthy_percent = 50
  deployment_maximum_percent         = 100
  lifecycle {
    ignore_changes = ["desired_count"]
  }
}
resource "aws_appautoscaling_target" "ecs_target" {
  max_capacity       = "${var.max_scalabe_capacity}"
  min_capacity       = "${var.min_scalabe_capacity}"
  resource_id        = "service/${var.ecs_cluster_name}/${aws_ecs_service.service.name}"
  scalable_dimension = "ecs:service:DesiredCount"
  service_namespace  = "ecs"
}
resource "aws_appautoscaling_policy" "cpu_based_scale_in_policy" {
  name               = "${var.service_name}-${var.env}-cpu-based-scale-in-policy"
  policy_type        = "StepScaling"
  resource_id        = "service/${var.ecs_cluster_name}/${var.service_name}"
  scalable_dimension = "ecs:service:DesiredCount"
  service_namespace  = "ecs"
  step_scaling_policy_configuration {
    adjustment_type         = "ChangeInCapacity"
    cooldown                = "${var.scale_in_cooldown_period}"
    metric_aggregation_type = "Average"
    step_adjustment {
      metric_interval_upper_bound = "${var.scale_in_step_adjustment_upper_bound}"
      scaling_adjustment          = "${var.scale_in_step_adjustment_scaling_adjustment}"
    }
  }
  depends_on = ["aws_appautoscaling_target.ecs_target"]
}

そして、これがモジュールの使用法です、

module "my_module" {
  source = "GIT_URL_FOR_MODULE"
  VARIABLES_AS_NEEDED_BY_MODULE
}
resource "aws_appautoscaling_policy" "queue_depth_based_scale_in_policy" {
  name               = "${local.service_name}-${local.env}-queue-scale-in-policy-new"
  policy_type        = "StepScaling"
  resource_id        = "service/${local.ecs_cluster_name}/${local.service_name}"
  scalable_dimension = "ecs:service:DesiredCount"
  service_namespace  = "ecs"
  step_scaling_policy_configuration {
    adjustment_type         = "ChangeInCapacity"
    cooldown                = "${local.queue_scale_in_cooldown_period}"
    metric_aggregation_type = "Average"
    step_adjustment {
      metric_interval_upper_bound = "${local.queue_scale_in_step_adjustment_upper_bound}"
      scaling_adjustment          = "${local.queue_scale_in_step_adjustment_scaling_adjustment}"
    }
  }
  depends_on = ["module.my_module"]
}

パイプラインで実行される手順は次のとおりです。

terraform get -update=true
terraform init
terraform taint -allow-missing -module=${MODULE_NAME} aws_ecs_task_definition.task_definition
terraform plan -out tfplan -input=false
terraform apply -input=false tfplan

このサイクルの背後にある理由を知りたいですか?

強調すべきもう 1 つのポイントは、すべてをゼロから再作成するterraform apply場合に成功することです。このサイクルは、タスク定義を行い、モジュールの外部に配置されたスケーリング ポリシーにいくつかの更新があるdestroy場合にのみ観察されます。taint

注: 私のパイプラインでは、以前のタスク定義を汚染して、サービスが新しいタスク定義で即座に開始されるようにします。そうしないと、タスクが新しいタスク定義ですぐにロールアウトされません。

4

1 に答える 1