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_definition
がapply
、これは正常に機能します。
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
注: 私のパイプラインでは、以前のタスク定義を汚染して、サービスが新しいタスク定義で即座に開始されるようにします。そうしないと、タスクが新しいタスク定義ですぐにロールアウトされません。