My company has 2 AWS accounts. On the first (lets call it playground), I have full administrative permissions. On the second (lets call it production) I have limited IAM permissions
I enabled AWS Config (using the terraform file on the appendix) on both accounts.
- On the playground it runs smoothly, everything is fine.
- One the production, it fails. More specifically, it fails to detect the account's resources with the message "Your resources are being discovered" as shown in the screenshot below.
I initially suspected this could be an IAM role permission issue.
e.g running
aws configservice list-discovered-resources --resource-type AWS::EC2::SecurityGroup --profile playground
gives me a list of the SecurityGroups discovered by the AWS Config on the playground (pretty much what I see on the console dashboard).
On the other hand:
aws configservice list-discovered-resources --resource-type AWS::EC2::SecurityGroup --profile production
returns a null list (there are security groups though. Same results with other types such as AWS::EC2::Instance
)
{
"resourceIdentifiers": []
}
Since the IAM role does have the rights to make describe API calls, I discarded the IAM permission suspicion. It works. It is just that it returns null.
Could it be the AWS Config role AWSServiceRoleForConfig
? It does not make sense. Since this is a Service Linked Role it should by default have all the required permissions. (Will append the policy at the end of the post nevertheless)
Now the weird part:
My rules validate some resources (e.g EFS) but throw this message: The specified resource is either unknown or has not been discovered.
I am still suspecting this might be an IAM issue, but I can't figure out what is going on. I've been strugglingwith this for days, I could really use some help here.
According to the official docs:
AWS Config keeps track of all changes to your resources by invoking the Describe or the List API call for each resource in your account. The service uses those same API calls to capture configuration details for all related resources.
config.tf
# Create the configuration recorder
resource "aws_config_configuration_recorder" "default" {
name = "default-recorder"
role_arn = "arn:aws:iam::${var.account_id}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig"
recording_group {
all_supported = true
include_global_resource_types = true
}
}
# Enable the configuration recorder
resource "aws_config_configuration_recorder_status" "default" {
name = aws_config_configuration_recorder.default.name
is_enabled = true
depends_on = [aws_config_delivery_channel.default]
}
# Connect AWS Config to the S3 bucket
resource "aws_config_delivery_channel" "default" {
name = "default-channel"
s3_bucket_name = "central-config-bucket" # Central S3 bucket
depends_on = [aws_config_configuration_recorder.default]
}
# Deploy the default HIPAA compliance comformance pack
resource "aws_config_conformance_pack" "hipaa" {
name = "operational-best-practices-for-HIPAA-Security"
template_body = data.http.conformance_pack.body
}
data "http" "conformance_pack" {
url = "https://raw.githubusercontent.com/awslabs/aws-config-rules/master/aws-config-conformance-packs/Operational-Best-Practices-for-HIPAA-Security.yaml"
}
resource "aws_config_aggregate_authorization" "main" {
account_id = "************"
region = "eu-central-1"
}
The default AWSServiceRoleForConfig policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"acm:DescribeCertificate",
"acm:ListCertificates",
"acm:ListTagsForCertificate",
"apigateway:GET",
"application-autoscaling:DescribeScalableTargets",
"application-autoscaling:DescribeScalingPolicies",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeLifecycleHooks",
"autoscaling:DescribePolicies",
"autoscaling:DescribeScheduledActions",
"autoscaling:DescribeTags",
"backup:DescribeBackupVault",
"backup:DescribeRecoveryPoint",
"backup:GetBackupPlan",
"backup:GetBackupSelection",
"backup:GetBackupVaultAccessPolicy",
"backup:GetBackupVaultNotifications",
"backup:ListBackupPlans",
"backup:ListBackupSelections",
"backup:ListBackupVaults",
"backup:ListRecoveryPointsByBackupVault",
"backup:ListTags",
"cloudformation:DescribeType",
"cloudformation:ListTypes",
"cloudfront:ListTagsForResource",
"cloudtrail:DescribeTrails",
"cloudtrail:GetEventSelectors",
"cloudtrail:GetTrailStatus",
"cloudtrail:ListTags",
"cloudwatch:DescribeAlarms",
"codepipeline:GetPipeline",
"codepipeline:GetPipelineState",
"codepipeline:ListPipelines",
"config:BatchGet*",
"config:Describe*",
"config:Get*",
"config:List*",
"config:Put*",
"config:Select*",
"dax:DescribeClusters",
"dms:DescribeReplicationInstances",
"dms:DescribeReplicationSubnetGroups",
"dms:ListTagsForResource",
"dynamodb:DescribeContinuousBackups",
"dynamodb:DescribeLimits",
"dynamodb:DescribeTable",
"dynamodb:ListTables",
"dynamodb:ListTagsOfResource",
"ec2:Describe*",
"ec2:GetEbsEncryptionByDefault",
"ecr:DescribeRepositories",
"ecr:GetLifecyclePolicy",
"ecr:GetRepositoryPolicy",
"ecr:ListTagsForResource",
"ecs:DescribeClusters",
"ecs:DescribeServices",
"ecs:DescribeTaskDefinition",
"ecs:DescribeTaskSets",
"ecs:ListClusters",
"ecs:ListServices",
"ecs:ListTagsForResource",
"ecs:ListTaskDefinitions",
"eks:DescribeCluster",
"eks:DescribeNodegroup",
"eks:ListClusters",
"eks:ListNodegroups",
"elasticache:DescribeCacheClusters",
"elasticache:DescribeCacheParameterGroups",
"elasticache:DescribeCacheSubnetGroups",
"elasticache:DescribeReplicationGroups",
"elasticfilesystem:DescribeAccessPoints",
"elasticfilesystem:DescribeBackupPolicy",
"elasticfilesystem:DescribeFileSystemPolicy",
"elasticfilesystem:DescribeFileSystems",
"elasticfilesystem:DescribeLifecycleConfiguration",
"elasticfilesystem:DescribeMountTargets",
"elasticfilesystem:DescribeMountTargetSecurityGroups",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeLoadBalancerPolicies",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeTags",
"elasticmapreduce:DescribeCluster",
"elasticmapreduce:DescribeSecurityConfiguration",
"elasticmapreduce:GetBlockPublicAccessConfiguration",
"elasticmapreduce:ListClusters",
"elasticmapreduce:ListInstances",
"es:DescribeElasticsearchDomain",
"es:DescribeElasticsearchDomains",
"es:ListDomainNames",
"es:ListTags",
"guardduty:GetDetector",
"guardduty:GetFindings",
"guardduty:GetMasterAccount",
"guardduty:ListDetectors",
"guardduty:ListFindings",
"iam:GenerateCredentialReport",
"iam:GetAccountAuthorizationDetails",
"iam:GetAccountPasswordPolicy",
"iam:GetAccountSummary",
"iam:GetCredentialReport",
"iam:GetGroup",
"iam:GetGroupPolicy",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:GetUser",
"iam:GetUserPolicy",
"iam:ListAttachedGroupPolicies",
"iam:ListAttachedRolePolicies",
"iam:ListAttachedUserPolicies",
"iam:ListEntitiesForPolicy",
"iam:ListGroupPolicies",
"iam:ListGroupsForUser",
"iam:ListInstanceProfilesForRole",
"iam:ListPolicyVersions",
"iam:ListRolePolicies",
"iam:ListUserPolicies",
"iam:ListVirtualMFADevices",
"kinesis:DescribeStreamSummary",
"kinesis:ListStreams",
"kinesis:ListTagsForStream",
"kms:DescribeKey",
"kms:GetKeyPolicy",
"kms:GetKeyRotationStatus",
"kms:ListKeys",
"kms:ListResourceTags",
"lambda:GetAlias",
"lambda:GetFunction",
"lambda:GetPolicy",
"lambda:ListAliases",
"lambda:ListFunctions",
"logs:DescribeLogGroups",
"organizations:DescribeOrganization",
"rds:DescribeDBClusters",
"rds:DescribeDBClusterSnapshotAttributes",
"rds:DescribeDBClusterSnapshots",
"rds:DescribeDBInstances",
"rds:DescribeDBSecurityGroups",
"rds:DescribeDBSnapshotAttributes",
"rds:DescribeDBSnapshots",
"rds:DescribeDBSubnetGroups",
"rds:DescribeEventSubscriptions",
"rds:ListTagsForResource",
"redshift:DescribeClusterParameterGroups",
"redshift:DescribeClusterParameters",
"redshift:DescribeClusters",
"redshift:DescribeClusterSecurityGroups",
"redshift:DescribeClusterSnapshots",
"redshift:DescribeClusterSubnetGroups",
"redshift:DescribeEventSubscriptions",
"redshift:DescribeLoggingStatus",
"route53:GetHostedZone",
"route53:ListHostedZones",
"route53:ListHostedZonesByName",
"route53:ListResourceRecordSets",
"route53:ListTagsForResource",
"s3:GetAccelerateConfiguration",
"s3:GetAccessPoint",
"s3:GetAccessPointPolicy",
"s3:GetAccessPointPolicyStatus",
"s3:GetAccountPublicAccessBlock",
"s3:GetBucketAcl",
"s3:GetBucketCORS",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketNotification",
"s3:GetBucketObjectLockConfiguration",
"s3:GetBucketPolicy",
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketRequestPayment",
"s3:GetBucketTagging",
"s3:GetBucketVersioning",
"s3:GetBucketWebsite",
"s3:GetEncryptionConfiguration",
"s3:GetLifecycleConfiguration",
"s3:GetReplicationConfiguration",
"s3:ListAccessPoints",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"sagemaker:DescribeCodeRepository",
"sagemaker:DescribeEndpointConfig",
"sagemaker:DescribeNotebookInstance",
"sagemaker:ListCodeRepositories",
"sagemaker:ListEndpointConfigs",
"sagemaker:ListNotebookInstances",
"sagemaker:ListTags",
"secretsmanager:ListSecrets",
"secretsmanager:ListSecretVersionIds",
"securityhub:describeHub",
"shield:DescribeDRTAccess",
"shield:DescribeProtection",
"shield:DescribeSubscription",
"sns:GetTopicAttributes",
"sns:ListSubscriptions",
"sns:ListTagsForResource",
"sns:ListTopics",
"sqs:GetQueueAttributes",
"sqs:ListQueues",
"sqs:ListQueueTags",
"ssm:DescribeAutomationExecutions",
"ssm:DescribeDocument",
"ssm:GetAutomationExecution",
"ssm:GetDocument",
"ssm:ListDocuments",
"storagegateway:ListGateways",
"storagegateway:ListVolumes",
"support:DescribeCases",
"tag:GetResources",
"waf-regional:GetLoggingConfiguration",
"waf-regional:GetWebACL",
"waf-regional:GetWebACLForResource",
"waf:GetLoggingConfiguration",
"waf:GetWebACL",
"wafv2:GetLoggingConfiguration"
],
"Resource": "*"
}
]
}
This was likely a AWS terraform provider bug.
The service linked role
AWSServiceRoleForConfig
does not get activated automatically the first time you apply the terraform plan. You need to manually add it to AWS config. Then it works fine.EDIT
The solution could be another than the aforementioned (or a combination of both). I also noticed that AWS Config get stuck on "resources are being discovered" when there are no rules/conformance packs deployed. If you deploy a single rule it discovers resources (?!)