Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new policy resources per DataDog docs #67

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

StealthBadger747
Copy link

what

why

I saw the following on my DataDog AWS Integration page:

Screenshot 2024-10-24 at 4 13 20 PM

@StealthBadger747 StealthBadger747 requested review from a team as code owners October 24, 2024 23:13
@mergify mergify bot added the triage Needs triage label Oct 24, 2024
@StealthBadger747
Copy link
Author

/terratest

Copy link
Member

@joe-niland joe-niland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @StealthBadger747 - just a few small things

resource "aws_iam_policy" "resource_collection" {
count = local.resource_collection_count
name = module.resource_collection_label.id
policy = data.aws_iam_policy_document.resource_collection[0].json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
policy = data.aws_iam_policy_document.resource_collection[0].json
policy = join("", data.aws_iam_policy_document.resource_collection.*.json)


resource "aws_iam_role_policy_attachment" "resource_collection" {
count = local.resource_collection_count
role = aws_iam_role.default[0].name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
role = aws_iam_role.default[0].name
role = join("", aws_iam_role.default.*.name)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joe-niland The new standard is

Suggested change
role = aws_iam_role.default[0].name
role = one(aws_iam_role.default[*].name)

resource "aws_iam_role_policy_attachment" "resource_collection" {
count = local.resource_collection_count
role = aws_iam_role.default[0].name
policy_arn = aws_iam_policy.resource_collection[0].arn
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
policy_arn = aws_iam_policy.resource_collection[0].arn
policy_arn = join("", aws_iam_policy.resource_collection.*.arn)

@@ -126,3 +123,59 @@ resource "aws_iam_role_policy_attachment" "all" {
role = join("", aws_iam_role.default.*.name)
policy_arn = join("", aws_iam_policy.all.*.arn)
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent, it would be good to have the below in iam_policy_resource-collection.tf

all_count = local.enabled && contains(split(",", lower(join(",", var.integrations))), "all") ? 1 : 0
integrations = split(",", lower(join(",", var.integrations)))
all_count = local.enabled && contains(local.integrations, "all") ? 1 : 0
resource_collection_count = local.enabled && contains(local.integrations, "resource_collection") ? 1 : 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also move to iam_policy_resource-collection.tf

@RoseSecurity
Copy link

@joe-niland Do you think it would be appropriate to parameterize these permissions so that users can add permissions as needed for their environments instead of having hardcoded lists that need updating? Could be a similar pattern to providing a base set of permissions that can be added to per environment as needed

@Nuru
Copy link
Contributor

Nuru commented Oct 30, 2024

@StealthBadger747 Thank you for this PR. It appears Datadog has made several changes/updates and we need to make some more significant changes. This will become a Major release, although I would like it to not have any breaking changes anyway.

If you are up for it, please change as follows (and if you are not up for it, no problem, we will get to it eventually, but probably not soon, or maybe @RoseSecurity will want to do it):

[ ] Style update: change all join("", resource.kind.*.name) and resource.kind[0].name to one(resource.kind[*].name) (unless there could be more than one, of course).

[ ] Deprecate var.integrations and add var.policies in its place.

To deprecate var.integrations:

  1. Update the description to indicate it is deprecated
  2. Make its default value null

To add var.policies

variable "policies" {
  type        = list(string)
  description = <<-EOT
    List of Datadog's names for AWS IAM policies names to apply to the role.
    Valid options are "core-integration", "full-integration", "resource-collection", "CSMP", "SecurityAudit", "everything".
    "CSMP" is for Cloud Security Posture Management, which also requires "full-integration".
    "SecurityAudit" is for the AWS-managed `SecurityAudit` Policy. 
    "everything" means all permissions for offerings.
    EOT
}

Create a local.policies which is the list of policies specified via var.integrations and var.policies combined with mappings and then de-duplicated.

For compatibility, map var.integrations "core" -> "core_integration" and "all" -> "full_integration" when adding to local.policies.

Consider "CSMP" an alias for "SecurityAudit".

[ ] Rename the "all" policy "full-integration" and update it.

Rename iam_policy_all.tf -> iam-policy-full-integration.tf and rename all the resources etc. named "all" to "full_integration", and trigger it with policy name "full-integration".

Update the policy reference to

https://docs.datadoghq.com/integrations/amazon_web_services/?tab=roledelegation#aws-integration-iam-policy
https://datadog-cloudformation-template.s3.amazonaws.com/aws/datadog_integration_role.yaml

Update the permissions (statement.actions) from those sources (you probably already did this, but please keep it exactly as on the website, except for whitespace):

full-integration permissions
  actions = [
    "apigateway:GET",
    "autoscaling:Describe*",
    "backup:List*",
    "budgets:ViewBudget",
    "cloudfront:GetDistributionConfig",
    "cloudfront:ListDistributions",
    "cloudtrail:DescribeTrails",
    "cloudtrail:GetTrailStatus",
    "cloudtrail:LookupEvents",
    "cloudwatch:Describe*",
    "cloudwatch:Get*",
    "cloudwatch:List*",
    "codedeploy:List*",
    "codedeploy:BatchGet*",
    "directconnect:Describe*",
    "dynamodb:List*",
    "dynamodb:Describe*",
    "ec2:Describe*",
    "ec2:GetTransitGatewayPrefixListReferences",
    "ec2:SearchTransitGatewayRoutes",
    "ecs:Describe*",
    "ecs:List*",
    "elasticache:Describe*",
    "elasticache:List*",
    "elasticfilesystem:DescribeFileSystems",
    "elasticfilesystem:DescribeTags",
    "elasticfilesystem:DescribeAccessPoints",
    "elasticloadbalancing:Describe*",
    "elasticmapreduce:List*",
    "elasticmapreduce:Describe*",
    "es:ListTags",
    "es:ListDomainNames",
    "es:DescribeElasticsearchDomains",
    "events:CreateEventBus",
    "fsx:DescribeFileSystems",
    "fsx:ListTagsForResource",
    "health:DescribeEvents",
    "health:DescribeEventDetails",
    "health:DescribeAffectedEntities",
    "kinesis:List*",
    "kinesis:Describe*",
    "lambda:GetPolicy",
    "lambda:List*",
    "logs:DeleteSubscriptionFilter",
    "logs:DescribeLogGroups",
    "logs:DescribeLogStreams",
    "logs:DescribeSubscriptionFilters",
    "logs:FilterLogEvents",
    "logs:PutSubscriptionFilter",
    "logs:TestMetricFilter",
    "oam:ListSinks",
    "oam:ListAttachedLinks",
    "organizations:Describe*",
    "organizations:List*",
    "rds:Describe*",
    "rds:List*",
    "redshift:DescribeClusters",
    "redshift:DescribeLoggingStatus",
    "route53:List*",
    "s3:GetBucketLogging",
    "s3:GetBucketLocation",
    "s3:GetBucketNotification",
    "s3:GetBucketTagging",
    "s3:ListAllMyBuckets",
    "s3:PutBucketNotification",
    "ses:Get*",
    "sns:List*",
    "sns:Publish",
    "sns:GetSubscriptionAttributes",
    "sqs:ListQueues",
    "states:ListStateMachines",
    "states:DescribeStateMachine",
    "support:DescribeTrustedAdvisor*",
    "support:RefreshTrustedAdvisorCheck",
    "tag:GetResources",
    "tag:GetTagKeys",
    "tag:GetTagValues",
    "wafv2:ListLoggingConfigurations",
    "wafv2:GetLoggingConfiguration",
    "xray:BatchGetTraces",
    "xray:GetTraceSummaries"
  ],

[ ] Rename iam_policy_core.tf -> iam-policy-core-integration.tf and rename all the resources etc. named "core" to "core_integration", and trigger it with policy name "core-integration".

Update the policy reference to

https://datadog-cloudformation-template.s3.amazonaws.com/aws/datadog_integration_role.yaml
in the "else" clause of `!If GrantFullPermissions`

Update the permissions (statement.actions) by removing 'support:*'

[ ] Create iam-policy-resource-collection.tf

Follow the pattern of iam-policy-full-integration.tf and create iam-policy-resource-collection.tf to implement the resource-collection option, referencing and using the policy from https://docs.datadoghq.com/integrations/amazon_web_services/?tab=roledelegation#aws-resource-collection-iam-policy-1

resource-collection permissions
  actions = [
    "backup:ListRecoveryPointsByBackupVault",
    "bcm-data-exports:GetExport",
    "bcm-data-exports:ListExports",
    "cassandra:Select",
    "cur:DescribeReportDefinitions",
    "ec2:GetSnapshotBlockPublicAccessState",
    "glacier:GetVaultNotifications",
    "glue:ListRegistries",
    "lightsail:GetInstancePortStates",
    "savingsplans:DescribeSavingsPlanRates",
    "savingsplans:DescribeSavingsPlans",
    "timestream:DescribeEndpoints",
    "waf-regional:ListRuleGroups",
    "waf-regional:ListRules",
    "waf:ListRuleGroups",
    "waf:ListRules",
    "wafv2:GetIPSet",
    "wafv2:GetRegexPatternSet",
    "wafv2:GetRuleGroup"
  ],

[ ] Create iam-policy-SecurityAudit.tf

Skip most of the content of the other files. I think it can be just

locals {
  security_audit_count = local.enabled && 
    (contains(var.policies, "CSPM") || contains(var.policies, "SecurityAudit")) ? 1 : 0
}

resource "aws_iam_role_policy_attachment" "security_audit" {
  count      = local.security_audit_count
  role       = one(aws_iam_role.default[*].name)
  policy_arn = "arn:aws:iam::aws:policy/SecurityAudit"
}

Copy link
Contributor

@Nuru Nuru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

@StealthBadger747
Copy link
Author

Just got caught up on my emails. @Nuru thanks for taking a look. I have personally deployed these changes in my workplace's environment at this point, but I would like to still see upstream changes.

At the moment I'm a bit busy with some other issues internally, but I will be working on a lot of Datadog things next week so I might be able to get to this then. It looks like I can implement these changes. I would also be happy to sync with @RoseSecurity if they might want to pick this up, or take more suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage Needs triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants