Skip to content

Commit

Permalink
Copying Stack tags to the Datadog monitor (#226)
Browse files Browse the repository at this point in the history
Cloudformation supports tags at a stack level. They are normally passed on to all Cloudformation resources (some resources don't support that yet...). Datadog monitors got tags, too. With this change, the Cloudformation Stack tags are copied to the Datadog monitor. Additionally, the AWS autogenerated tags like stack name and logical id are also set. If a tag is already set explicitly at a monitor, the monitor value is being used.
Since Datadog uses a : to separate key and value, all : are replaced with _.

In order to maintain backwards compatibility, this feature is switched off by default. It can be enabled account-wide via the type configuration, the same way Datadog credentials are being set.
  • Loading branch information
elruwen authored and skarimo committed Nov 21, 2022
1 parent d85c1dc commit 66b6d18
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
"properties": {
"DatadogCredentials": {
"$ref": "#/definitions/DatadogCredentials"
},
"TagResourceWithStackTags": {
"description": "Copy the Cloudformation Stack tags to the datadog monitor. It defaults to false to stay backwards compatible.",
"type": "boolean"
}
},
"additionalProperties": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
"properties": {
"DatadogCredentials": {
"$ref": "#/definitions/DatadogCredentials"
},
"TagResourceWithStackTags": {
"description": "Copy the Cloudformation Stack tags to the datadog monitor. It defaults to false to stay backwards compatible.",
"type": "boolean"
}
},
"additionalProperties": false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ def update_handler(
monitor.name = model.Name
if model.Tags is not None:
monitor.tags = model.Tags
_copy_stack_tags(monitor, request)
if model.Priority is not None:
monitor.priority = model.Priority
if model.RestrictedRoles is not None:
Expand Down Expand Up @@ -249,6 +250,7 @@ def create_handler(
monitor.name = model.Name
if model.Tags is not None:
monitor.tags = model.Tags
_copy_stack_tags(monitor, request)
if model.Priority is not None:
monitor.priority = model.Priority
if model.RestrictedRoles is not None:
Expand Down Expand Up @@ -333,3 +335,22 @@ def build_monitor_options_from_model(model: ResourceModel) -> ApiMonitorOptions:
options.threshold_windows.recovery_window = model.Options.ThresholdWindows.RecoveryWindow

return options


def _copy_stack_tags(monitor: ApiMonitor, request: ResourceHandlerRequest):
if request.typeConfiguration.TagResourceWithStackTags:
tags_to_copy = dict(**request.systemTags)
if request.desiredResourceTags:
tags_to_copy.update(**request.desiredResourceTags)

monitor.tags = monitor.get("tags", [])
for k, v in tags_to_copy.items():
# we also replace the : in the tag name to avoid issues with datadog's tagging format
k = k.replace(':', '_')
found = False
for existing_tag in monitor.tags:
if existing_tag.startswith(f"{k}:"):
found = True
break
if not found:
monitor.tags.append(f"{k}:{v}")
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ def _deserialize(
@dataclass
class TypeConfigurationModel(BaseModel):
DatadogCredentials: Optional["_DatadogCredentials"]
TagResourceWithStackTags: Optional[bool]

@classmethod
def _deserialize(
Expand All @@ -231,6 +232,7 @@ def _deserialize(
return None
return cls(
DatadogCredentials=DatadogCredentials._deserialize(json_data.get("DatadogCredentials")),
TagResourceWithStackTags=json_data.get("TagResourceWithStackTags"),
)


Expand Down

0 comments on commit 66b6d18

Please sign in to comment.