Hi all,
I’m trying to deploy AWS GuardDuty to an organization with administration of the service delegated to a particular account. I have this working in an organization of accounts in the commercial partition but in this GovCloud organization I just get BadRequestException: The request is rejected because an invalid or out-of-range value is specified as an input parameter.
I understand that malware_protection
is not available in GovCloud and I have it disabled in the datasources
block in aws_guardduty_detector
. I also have auto-enable
set to false in aws_guardduty_organization_configuration
. I always get the same error. If I remove all mention of malware_protection
I still get the error. Any Idea what I’m missing?
Here’s what I’m trying to run in the administration account:
resource "aws_guardduty_detector" "comm_detector" {
count = var.govcloud ? 0 : 1
enable = true
datasources {
s3_logs {
enable = true
}
kubernetes {
audit_logs {
enable = false
}
}
malware_protection {
scan_ec2_instance_with_findings {
ebs_volumes {
enable = true
}
}
}
}
}
resource "aws_guardduty_detector" "govcloud_detector" {
count = var.govcloud ? 1 : 0
enable = true
datasources {
s3_logs {
enable = true
}
kubernetes {
audit_logs {
enable = false
}
}
malware_protection {
scan_ec2_instance_with_findings {
ebs_volumes {
enable = false
}
}
}
}
}
resource "aws_guardduty_organization_configuration" "comm_config" {
count = var.govcloud ? 0 : 1
auto_enable_organization_members = "ALL"
detector_id = aws_guardduty_detector.comm_detector[0].id
datasources {
s3_logs {
auto_enable = true
}
malware_protection {
scan_ec2_instance_with_findings {
ebs_volumes {
auto_enable = true
}
}
}
}
}
resource "aws_guardduty_organization_configuration" "govcloud_config" {
count = var.govcloud ? 1 : 0
auto_enable_organization_members = "ALL"
detector_id = aws_guardduty_detector.govcloud_detector[0].id
datasources {
s3_logs {
auto_enable = true
}
malware_protection {
scan_ec2_instance_with_findings {
ebs_volumes {
auto_enable = false
}
}
}
}
}
resource "aws_guardduty_member" "members" {
detector_id = var.govcloud ? aws_guardduty_detector.govcloud_detector[0].id : aws_guardduty_detector.comm_detector[0].id
account_id = element(keys(var.accounts_emails), count.index)
email = element(values(var.accounts_emails), count.index)
invite = true
count = length(keys(var.accounts_emails))
}
Some more specific questions.
- I have configured GuardDuty the way I want it through the console. Running
get-detector
CLI command I’m given a list of datasources and a list of features. Running the describe-organization-configuration
command I get different lists of datasources and features. I know this is not a Terraform question but maybe someone can help me understand the difference between the two?
aws guardduty get-detector --detector-id xxxxxxxxxxxxxxxx
{
"CreatedAt": "2023-11-06T14:05:45.374Z",
"FindingPublishingFrequency": "SIX_HOURS",
"ServiceRole": "arn:aws-us-gov:iam::614497914326:role/aws-service-role/guardduty.amazonaws.com/AWSServiceRoleForAmazonGuardDuty",
"Status": "ENABLED",
"UpdatedAt": "2023-11-06T14:51:53.334Z",
"DataSources": {
"CloudTrail": {
"Status": "ENABLED"
},
"DNSLogs": {
"Status": "ENABLED"
},
"FlowLogs": {
"Status": "ENABLED"
},
"S3Logs": {
"Status": "ENABLED"
},
"Kubernetes": {
"AuditLogs": {
"Status": "ENABLED"
}
}
},
"Tags": {},
"Features": [
{
"Name": "CLOUD_TRAIL",
"Status": "ENABLED",
"UpdatedAt": "2023-11-07T09:51:40+00:00"
},
{
"Name": "DNS_LOGS",
"Status": "ENABLED",
"UpdatedAt": "2023-11-07T09:51:40+00:00"
},
{
"Name": "FLOW_LOGS",
"Status": "ENABLED",
"UpdatedAt": "2023-11-07T09:51:40+00:00"
},
{
"Name": "S3_DATA_EVENTS",
"Status": "ENABLED",
"UpdatedAt": "2023-11-06T14:50:05+00:00"
},
{
"Name": "EKS_AUDIT_LOGS",
"Status": "ENABLED",
"UpdatedAt": "2023-11-06T14:50:47+00:00"
},
{
"Name": "LAMBDA_NETWORK_LOGS",
"Status": "ENABLED",
"UpdatedAt": "2023-11-06T14:51:53+00:00"
}
]
}
aws guardduty describe-organization-configuration --detector-id xxxxxxxxxxxxxxxx
{
"AutoEnable": true,
"MemberAccountLimitReached": false,
"DataSources": {
"S3Logs": {
"AutoEnable": true
},
"Kubernetes": {
"AuditLogs": {
"AutoEnable": true
}
}
},
"Features": [
{
"Name": "S3_DATA_EVENTS",
"AutoEnable": "ALL"
},
{
"Name": "LAMBDA_NETWORK_LOGS",
"AutoEnable": "ALL"
},
{
"Name": "EKS_AUDIT_LOGS",
"AutoEnable": "ALL"
}
],
"AutoEnableOrganizationMembers": "ALL"
}
-
The datasources can be set in both of the Terraform resources aws_guardduty_detector
and aws_guardduty_organization_configuration
. The example in the docs for aws_guardduty_organization_configuration
show a detector but without datasources. When would datasources need to be specified in the detector?
-
The datasources and features output above differ from what the Terraform docs say is available in the aws_guardduty_detector
resource (i.e. CLOUD_TRAIL
, DNS_LOGS
). This this an omission in the docs or are these datasources/features not available through Terraform?
-
When applying an aws_guardduty_detector
or aws_guardduty_organization_configuration
, if malware_protection
is left out, Terraform appears to try to enable it due to the default settings enable = true
(detector) and auto_enable = true
(detector config). This is not available in GovCloud. If both are set to false
I get the BadRequestException
error in my last comment. Is Terraform trying to configure a feature that the AWS API does not recognise, i.e. malware_protection
in GovCloud?
More testing.
- Ran a
destroy
in two GovCloud regions to start from the start.
- Set up GuardDuty through the console for one region.
- Imported detector and configuration resources into the state.
- Ran targeted
apply
on detector and configuration resources. Plans showed no changes. This validates the Terraform code as being in line with what I need deployed on AWS platform.
- Ran targeted
apply
on detector and configuration resources in second region without first setting it up in the console and importing. Detector created successfully, configuration throws BadRequestException
error.
My conclusion from this is that Terraform cannot be used to create a GuardDuty detector configuration in the GovCloud partition. If the config is created through the console and imported, the apply
sees the resource in the state and makes and doesn’t attempt to create it. Terraform, when creating it, send values (default or otherwise) for attributes relating to malware protection. These are not recognised in GovCloud and the result is the API request generates an error.
Sooo. Whatcha think?