Tracking Changes in AWS Resource Tagging Over Time
Getting Started with CloudQuery #
aws_lambda_functions
. However, you can use any AWS resource. Your schema will contain the _cq_sync_time
, arn
and tags
columns for any AWS resource.write_mode: append
in your CloudQuery destination configuration and deterministic_cq_id: true
in your AWS configuration. Here is an example using the PostgreSQL Destination Plugin:kind: source
spec:
name: "aws"
path: "cloudquery/aws"
version: "VERSION_SOURCE_AWS"
tables: ["aws_lambda_functions"]
deterministic_cq_id: true
destinations: ["postgresql"]
spec:
---
kind: destination
spec:
name: "postgresql"
path: "cloudquery/postgresql"
version: "VERSION_DESTINATION_POSTGRESQL"
write_mode: "append"
spec:
connection_string: "<YOUR_POSTGRES_CONNECTION_STRING>"
Tracking AWS Lambda Function Tags #
Lag()
window function in combination with a few PostgreSQL JSON functions.WITH prev_tag AS (
SELECT
arn,
_cq_sync_time,
tags,
LAG(tags) OVER (PARTITION BY arn ORDER BY _cq_sync_time) AS previous_tags
FROM
aws_lambda_functions
ORDER BY
arn, _cq_sync_time
)
SELECT
_cq_sync_time,
arn,
tags,
previous_tags,
jsonb_build_object(
'removed',
(
SELECT jsonb_object_agg(key, value)
FROM (
SELECT j1.key, j1.value
FROM jsonb_each(previous_tags) j1
LEFT JOIN jsonb_each(tags) j2 ON j1.key = j2.key
WHERE j2.key IS NULL
) AS removed
),
'added',
(
SELECT jsonb_object_agg(key, value)
FROM (
SELECT j1.key, j1.value
FROM jsonb_each(tags) j1
LEFT JOIN jsonb_each(previous_tags) j2 ON j1.key = j2.key
WHERE j2.key IS NULL
) AS added
),
'changed',
(
SELECT jsonb_object_agg(key, value)
FROM (
SELECT j1.key, j1.value
FROM jsonb_each(tags) j1
JOIN jsonb_each(previous_tags) j2 ON j1.key = j2.key
WHERE j1.value <> j2.value
) AS changed
)
) AS tag_diff
FROM
prev_tag
WHERE previous_tags IS NOT NULL
ORDER BY arn, _cq_sync_time;
tag_diff
, which will hold a JSON showing the change between the tags from the previous sync to the current for each row. For example, if there is no change in tags, you will see:{
"added": null,
"changed": null,
"removed": null
}
{
"added": {
"Owner": "Bob"
},
"changed": null,
"removed": null
}
{
"added": null,
"changed": {
"Owner": "Alice"
},
"removed": null
}
{
"removed": {
"Owner": "Alice"
},
"added": null,
"changed": null
}
CREATE OR REPLACE FUNCTION jsonb_diff(tags JSONB, previous_tags JSONB)
RETURNS JSONB LANGUAGE plpgsql AS $$
BEGIN
RETURN jsonb_build_object(
'removed',
(
SELECT jsonb_object_agg(key, value)
FROM (
SELECT j1.key, j1.value
FROM jsonb_each(previous_tags) j1
LEFT JOIN jsonb_each(tags) j2 ON j1.key = j2.key
WHERE j2.key IS NULL
) AS removed
),
'added',
(
SELECT jsonb_object_agg(key, value)
FROM (
SELECT j1.key, j1.value
FROM jsonb_each(tags) j1
LEFT JOIN jsonb_each(previous_tags) j2 ON j1.key = j2.key
WHERE j2.key IS NULL
) AS added
),
'changed',
(
SELECT jsonb_object_agg(key, value)
FROM (
SELECT j1.key, j1.value
FROM jsonb_each(tags) j1
JOIN jsonb_each(previous_tags) j2 ON j1.key = j2.key
WHERE j1.value <> j2.value
) AS changed
)
);
END;
$$;
WITH prev_tag AS (
SELECT
arn,
_cq_sync_time,
tags,
LAG(tags) OVER (PARTITION BY arn ORDER BY _cq_sync_time) AS previous_tags
FROM
aws_lambda_functions
ORDER BY
arn, _cq_sync_time
)
SELECT
_cq_sync_time,
arn,
tags,
previous_tags,
jsonb_diff(tags, previous_tags) AS tag_diff
FROM
prev_tag
WHERE previous_tags IS NOT NULL
ORDER BY arn, _cq_sync_time;
aws_lambda_functions
with any table available from our AWS Source Plugin. This will enable you to monitor tag changes over time for the selected resource.Summary #
Written by Jonathan Sarig
Jonathan is a software engineer at CloudQuery with a particular interest in machine learning. He primarily works in golang but also has experience in (and a passion for) Rust.