Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions database-monitoring/terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ No modules.
| [aws_security_group.efs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
| [aws_vpc_security_group_ingress_rule.efs_from_agent](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
| [random_id.hash_secret](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource |
| [aws_ecs_service.runtime](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecs_service) | data source |
| [aws_ecs_task_definition.runtime](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecs_task_definition) | data source |
| [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |

## Inputs
Expand All @@ -202,6 +204,7 @@ No modules.
| <a name="input_name"></a> [name](#input_name) | What the product shows for this agent. Also the ECS cluster, service and task family name, sanitised to the characters ECS allows. | `string` | n/a | yes |
| <a name="input_persistent_ledger"></a> [persistent_ledger](#input_persistent_ledger) | Keep the agent's state on an encrypted EFS file system so it persists across task replacement. When false, the state is on the task's ephemeral storage and every replacement starts it empty. | `bool` | `true` | no |
| <a name="input_publication"></a> [publication](#input_publication) | Name of the publication whose tables are streamed. | `string` | `"elastio_monitor"` | no |
| <a name="input_runtime_updates"></a> [runtime_updates](#input_runtime_updates) | Preserve images selected by Elastio when applying infrastructure/size changes. Enable after the ECS service has first been created. | `bool` | `false` | no |
| <a name="input_security_group_ids"></a> [security_group_ids](#input_security_group_ids) | Security groups attached to the task. The database's own security group must admit them on its port. | `list(string)` | n/a | yes |
| <a name="input_server_url"></a> [server_url](#input_server_url) | Base URL of the server the agent reports to. | `string` | n/a | yes |
| <a name="input_slot"></a> [slot](#input_slot) | Name of the existing pgoutput replication slot. The agent never creates or drops one. | `string` | `"elastio_monitor"` | no |
Expand All @@ -223,3 +226,19 @@ No modules.
| <a name="output_task_role_arn"></a> [task_role_arn](#output_task_role_arn) | IAM role the running container assumes. The agent has no AWS code; with persistent state the role may mount the state file system, and nothing else. |

<!-- END_TF_DOCS -->

## Runtime image upgrades

After the first deployment, set `runtime_updates = true` when installing the
Elastio deployment updater. Manual updates and optional automatic upgrades are
then controlled through Elastio. Terraform continues to own infrastructure and
CPU/memory sizing. During a size change or later apply, the module reads the
service's current task definition and preserves its agent and detector images,
including immutable digests selected by the updater. It does not reset them to
the module's older `image` defaults. Do not enable this option on a first-ever
apply: the service must exist for its deployed images to be read.

The updater runs separately from the monitored task with permission to update
only its configured ECS service and pass the existing task/execution roles.
Installation and Docker/VM equivalents are documented in the
[agent updater guide](https://github.com/elastio/database-monitoring-agent/tree/master/deploy/updater).
4 changes: 2 additions & 2 deletions database-monitoring/terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ locals {

agent_container_base = {
name = "${local.prefix}-agent"
image = var.image
image = lookup(local.runtime_images, "elastio-dbmon-agent", var.image)
essential = true
user = "${local.uid}:${local.gid}"

Expand Down Expand Up @@ -134,7 +134,7 @@ locals {
# metrics to every interface). The agent needs no inbound rule at all.
ed_container = {
name = "${local.prefix}-ed"
image = var.ed_image
image = lookup(local.runtime_images, "elastio-dbmon-ed", var.ed_image)
essential = false
user = "${local.uid}:${local.gid}"
memory = local.ed_memory
Expand Down
25 changes: 25 additions & 0 deletions database-monitoring/terraform/runtime-updates.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# After bootstrap, Elastio owns image selection. Terraform reads the service's
# currently deployed images before changing size or infrastructure, so a later
# apply cannot restore an obsolete module image pin.
variable "runtime_updates" {
description = "Preserve images selected by Elastio when applying infrastructure/size changes. Enable after the ECS service has first been created."
type = bool
default = false
}

data "aws_ecs_service" "runtime" {
count = var.runtime_updates ? 1 : 0
service_name = local.ecs_name
cluster_arn = aws_ecs_cluster.this.arn
}

data "aws_ecs_task_definition" "runtime" {
count = var.runtime_updates ? 1 : 0
task_definition = data.aws_ecs_service.runtime[0].task_definition
}

locals {
runtime_images = var.runtime_updates ? {
for container in jsondecode(data.aws_ecs_task_definition.runtime[0].container_definitions) : container.name => container.image
} : {}
}
24 changes: 24 additions & 0 deletions database-monitoring/terraform/tests/module.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,27 @@ run "content_analysis_needs_room_for_the_detector" {

expect_failures = [var.content_analysis]
}

run "runtime_update_images_survive_size_changes" {
command = plan
variables {
runtime_updates = true
content_analysis = true
task_cpu = 1024
task_memory = 2048
image = "old-agent:0.1.9"
ed_image = "old-python:0.1.9"
}
override_data {
target = data.aws_ecs_service.runtime[0]
values = { task_definition = "arn:aws:ecs:us-east-1:123456789012:task-definition/runtime:7" }
}
override_data {
target = data.aws_ecs_task_definition.runtime[0]
values = { container_definitions = "[{\"name\":\"elastio-dbmon-agent\",\"image\":\"agent@sha256:new\"},{\"name\":\"elastio-dbmon-ed\",\"image\":\"native@sha256:new\"}]" }
}
assert {
condition = local.agent_container.image == "agent@sha256:new" && local.ed_container.image == "native@sha256:new" && aws_ecs_task_definition.this.cpu == "1024"
error_message = "Sizing must preserve the images selected by Elastio, including native ED."
}
}
Loading