I have three child modules and one parent module for ssm patching. One module in particular is different than the rest (RHEL) it will never need to be changed, so the child module was written differently.
I have my baseline approval rules written as a dynamic object and have prepared the variable for the object.
resource "aws_ssm_patch_baseline" "baseline" {
name = format("%s-%s-%s-baseline", var.patch_baseline_label, var.env, lower(local.operating_system))
description = var.description
operating_system = local.operating_system
approved_patches = var.approved_patches
rejected_patches = var.rejected_patches
approved_patches_compliance_level = var.compliance_level
dynamic "approval_rule" {
for_each = var.baseline_approval_rules
content {
approve_after_days = approval_rule.value.approve_after_days
compliance_level = approval_rule.value.compliance_level
enable_non_security = approval_rule.value.enable_non_security
# patch filter values : https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-patch-properties.html
dynamic "patch_filter" {
for_each = approval_rule.value.patch_baseline_filters
content {
key = patch_filter.value.name
values = patch_filter.value.values
}
}
}
}
tags = merge(var.tags, { Name = format("%s-%s-%s", var.patch_baseline_label, var.env, lower(local.operating_system)) })
}
The variable for the approval rules is written as such:
variable "baseline_approval_rules" {
description = "list of approval rules defined in the patch baseline (Max 10 rules). For compliance_level, it means that if an approved patch is reported as missing, this is the severity of the compliance violation. Valid compliance levels include the following: CRITICAL, HIGH, MEDIUM, LOW, INFORMATIONAL, UNSPECIFIED. The default value is UNSPECIFIED."
type = list(object({
approve_after_days : number
compliance_level : string
enable_non_security : bool
patch_baseline_filters : list(object({
name : string
values : list(string)
}))
}))
default = [
{
approve_after_days = 0
// The compliance level of a patch will default to unspecified if a patch isn't applied
compliance_level = "CRITICAL"
enable_non_security = false
patch_baseline_filters = [
{
name = "PRODUCT"
values = ["RedhatEnterpriseLinux6.10", "RedhatEnterpriseLinux6.5", "RedhatEnterpriseLinux6.6", "RedhatEnterpriseLinux6.7", "RedhatEnterpriseLinux6.8", "RedhatEnterpriseLinux6.9", "RedhatEnterpriseLinux7", "RedhatEnterpriseLinux7.0", "RedhatEnterpriseLinux7.1", "RedhatEnterpriseLinux7.2", "RedhatEnterpriseLinux7.3", "RedhatEnterpriseLinux7.4", "RedhatEnterpriseLinux7.5", "RedhatEnterpriseLinux7.6", "RedhatEnterpriseLinux7.7", "RedhatEnterpriseLinux7.8", "RedhatEnterpriseLinux8", "RedhatEnterpriseLinux8.0", "RedhatEnterpriseLinux8.1", "RedhatEnterpriseLinux8.2"]
},
{
name = "CLASSIFICATION"
values = ["Security"]
},
{
name = "SEVERITY"
values = ["Critical"]
}
]
}
]
}
In the parent module, I would like an output that generates a map for the baseline approval rules.. something similar to
[
{
name = "product",
valueFrom = <VALUE FROM PRODUCT IN patch_baseline_filters >,
{
name = "severity",
valueFrom = <VALUE FROM SEVERITY IN patch_baseline_filters>,
{
name = <etc>,
valueFrom = <ETC>
}
]
I'm trying to use functions like zipmap and sort to output the values to a map, but I have had no success.
Thanks!
EDIT:
Entire RHEL resource output looks like this:
+ entire_rhel_resource = [
+ {
+ approval_rule = [
+ {
+ approve_after_days = 0
+ approve_until_date = null
+ compliance_level = "CRITICAL"
+ enable_non_security = false
+ patch_filter = [
+ {
+ key = "PRODUCT"
+ values = [
+ "RedhatEnterpriseLinux6.10",
+ "RedhatEnterpriseLinux6.5",
+ "RedhatEnterpriseLinux6.6",
+ "RedhatEnterpriseLinux6.7",
+ "RedhatEnterpriseLinux6.8",
+ "RedhatEnterpriseLinux6.9",
+ "RedhatEnterpriseLinux7",
+ "RedhatEnterpriseLinux7.0",
+ "RedhatEnterpriseLinux7.1",
+ "RedhatEnterpriseLinux7.2",
+ "RedhatEnterpriseLinux7.3",
+ "RedhatEnterpriseLinux7.4",
+ "RedhatEnterpriseLinux7.5",
+ "RedhatEnterpriseLinux7.6",
+ "RedhatEnterpriseLinux7.7",
+ "RedhatEnterpriseLinux7.8",
+ "RedhatEnterpriseLinux8",
+ "RedhatEnterpriseLinux8.0",
+ "RedhatEnterpriseLinux8.1",
+ "RedhatEnterpriseLinux8.2",
]
},
+ {
+ key = "CLASSIFICATION"
+ values = [
+ "Security",
]
},
+ {
+ key = "SEVERITY"
+ values = [
+ "Critical",
]
},
]
},
]
+ approved_patches = null
+ approved_patches_compliance_level = "UNSPECIFIED"
+ approved_patches_enable_non_security = null
+ arn = (known after apply)
+ description = "RedHat Enterprise Linux Default Patch Baseline"
+ global_filter = []
+ id = (known after apply)
+ name = "SENSITIVEredhat_enterprise_linux-baseline"
+ operating_system = "REDHAT_ENTERPRISE_LINUX"
+ rejected_patches = null
+ rejected_patches_action = (known after apply)
+ source = []
+ tags = {
+ "Name" = "SENSITIVEredhat_enterprise_linux"
+ "owner" = "SENSITIVE"
+ "team" = "SENSITIVE"
+ "terraform" = "true"
}
+ tags_all = {
+ "Name" = "SENSITIVEredhat_enterprise_linux"
+ "owner" = "SENSITIVE"
+ "team" = "SENSITIVE"
+ "terraform" = "true"
}
},
]
Here is the best I could come up with:
output "rhel_server_types" {
description = "types of patches applied for rhel systems"
value = [for i in aws_ssm_patch_baseline.baseline.approval_rule[0].patch_filter : {
name = lower(i.key)
valueFrom = i.values
}]
}