A CloudWatch dashboard is a JSON document describing a grid of widgets. There is no drag-and-drop-only path required - PutDashboard accepts that JSON directly, which means dashboards can be generated, templated, and version-controlled exactly like the rest of your infrastructure.
This page covers building, reading, and updating dashboards from the SDK.
A log widget embeds a Logs Insights query directly - SOURCE '<log-group>' | <query> - and renders its results as a table or visualization.
GetDashboard returns DashboardBody as a JSON string you parse yourself; the SDK does not model widgets as typed objects.
Updating means reading, modifying the in-memory structure, and calling PutDashboard again with the full body - there is no widget-level patch operation.
A text widget renders markdown, useful for on-call links or runbook context alongside the metrics.
Every widget occupies a rectangle on a 24-column-wide grid, positioned by x/y and sized by width/height. There is no automatic layout - your code (or a human in the Console) decides where each widget goes.
Common widget type values:
Type
Renders
Key properties
metric
A graph or number of one or more metrics
metrics, period, stat, view (timeSeries, singleValue, bar, pie)
log
A Logs Insights query result
query (a SOURCE '<group>' | ... string), view (table, bar, pie, stacked)
PutDashboard always replaces the entire DashboardBody for that name. There is no operation to add or remove a single widget server-side - the pattern is always read (or hold in memory), modify the JSON, and re-put the whole thing, as shown in the working example.
This makes dashboards a good fit for generation: build the JSON from a list of services or metrics known at deploy time, and PutDashboard the result idempotently on every deploy.
Treating widgets as a typed SDK model - both SDKs pass DashboardBody through as an opaque string. Fix: build and validate the JSON shape yourself; a malformed widget only surfaces as a Console rendering error, not a client-side type error.
Trying to patch a single widget - there is no per-widget update API. Fix: always read, modify in memory, and PutDashboard the full body back.
Forgetting region in metric/log widget properties - a dashboard viewed from a different default region can show blank widgets. Fix: set region explicitly per widget rather than relying on account defaults.
Overlapping widget coordinates - manually computed x/y/width/height values can silently overlap. Fix: compute positions programmatically (a simple row/column layout function) instead of hardcoding by hand for larger dashboards.
Losing track of dashboard drift - manual Console edits get silently overwritten by the next PutDashboard call. Fix: treat the SDK/generator as the single source of truth once a dashboard is code-managed.
Not validating JSON before sending - a syntax error in DashboardBody fails the call with a generic validation error. Fix: parse your own generated JSON locally before calling PutDashboard to catch mistakes early.
No. It is always a plain JSON string in both boto3 and SDK v3 - you build and parse the widget structure yourself; the SDK does not model widgets as typed classes.
Can I update just one widget on a dashboard?
Not directly. PutDashboard replaces the entire DashboardBody for that name. Read the current body (or keep your generator's source of truth), modify it, and re-put the whole thing.
What widget types are available?
Common types are metric (graphs/numbers from CloudWatch metrics), log (a saved Logs Insights query), text (static markdown), and alarm (an alarm's state and history).
How does a log widget embed a Logs Insights query?
Its properties.query is a string in the form SOURCE '<log-group>' | <Logs Insights query>, rendered as a table or chart depending on view.
Is PutDashboard safe to call repeatedly?
Yes, it is idempotent by DashboardName - calling it again with the same name simply replaces the layout, which is what makes dashboard generation on every deploy practical.
Should I mix manual Console edits with SDK-managed dashboards?
Generally no. Once a dashboard is generated from code, manual Console edits get overwritten on the next PutDashboard call. Pick one source of truth per dashboard.