diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95dc1d3d3215..57503a70c637 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,9 @@ Main (unreleased)
 
 - A new `pyroscope.java` component for profiling Java processes using async-profiler. (@korniltsev)
 
+- A new `otelcol.processor.resourcedetection` component which inserts resource attributes 
+  to OTLP telemetry based on the host on which Grafana Agent is running. (@ptodev)
+  
 ### Enhancements
 
 - Include line numbers in profiles produced by `pyrsocope.java` component. (@korniltsev)
diff --git a/component/all/all.go b/component/all/all.go
index 437a7a07e59b..0bf3da725bbf 100644
--- a/component/all/all.go
+++ b/component/all/all.go
@@ -82,6 +82,7 @@ import (
 	_ "github.com/grafana/agent/component/otelcol/processor/k8sattributes"          // Import otelcol.processor.k8sattributes
 	_ "github.com/grafana/agent/component/otelcol/processor/memorylimiter"          // Import otelcol.processor.memory_limiter
 	_ "github.com/grafana/agent/component/otelcol/processor/probabilistic_sampler"  // Import otelcol.processor.probabilistic_sampler
+	_ "github.com/grafana/agent/component/otelcol/processor/resourcedetection"      // Import otelcol.processor.resourcedetection
 	_ "github.com/grafana/agent/component/otelcol/processor/span"                   // Import otelcol.processor.span
 	_ "github.com/grafana/agent/component/otelcol/processor/tail_sampling"          // Import otelcol.processor.tail_sampling
 	_ "github.com/grafana/agent/component/otelcol/processor/transform"              // Import otelcol.processor.transform
diff --git a/component/otelcol/config_k8s.go b/component/otelcol/config_k8s.go
new file mode 100644
index 000000000000..b20407fd41fb
--- /dev/null
+++ b/component/otelcol/config_k8s.go
@@ -0,0 +1,35 @@
+package otelcol
+
+import "fmt"
+
+const (
+	KubernetesAPIConfig_AuthType_None           = "none"
+	KubernetesAPIConfig_AuthType_ServiceAccount = "serviceAccount"
+	KubernetesAPIConfig_AuthType_KubeConfig     = "kubeConfig"
+	KubernetesAPIConfig_AuthType_TLS            = "tls"
+)
+
+// KubernetesAPIConfig contains options relevant to connecting to the K8s API
+type KubernetesAPIConfig struct {
+	// How to authenticate to the K8s API server.  This can be one of `none`
+	// (for no auth), `serviceAccount` (to use the standard service account
+	// token provided to the agent pod), or `kubeConfig` to use credentials
+	// from `~/.kube/config`.
+	AuthType string `river:"auth_type,attr,optional"`
+
+	// When using auth_type `kubeConfig`, override the current context.
+	Context string `river:"context,attr,optional"`
+}
+
+// Validate returns an error if the config is invalid.
+func (c *KubernetesAPIConfig) Validate() error {
+	switch c.AuthType {
+	case KubernetesAPIConfig_AuthType_None,
+		KubernetesAPIConfig_AuthType_ServiceAccount,
+		KubernetesAPIConfig_AuthType_KubeConfig,
+		KubernetesAPIConfig_AuthType_TLS:
+		return nil
+	default:
+		return fmt.Errorf("invalid auth_type %q", c.AuthType)
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/aws/ec2/config.go b/component/otelcol/processor/resourcedetection/internal/aws/ec2/config.go
new file mode 100644
index 000000000000..9b715eac4a12
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/aws/ec2/config.go
@@ -0,0 +1,72 @@
+package ec2
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "ec2"
+
+// Config defines user-specified configurations unique to the EC2 detector
+type Config struct {
+	// Tags is a list of regex's to match ec2 instance tag keys that users want
+	// to add as resource attributes to processed data
+	Tags               []string                 `river:"tags,attr,optional"`
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		CloudAccountID:        rac.ResourceAttributeConfig{Enabled: true},
+		CloudAvailabilityZone: rac.ResourceAttributeConfig{Enabled: true},
+		CloudPlatform:         rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider:         rac.ResourceAttributeConfig{Enabled: true},
+		CloudRegion:           rac.ResourceAttributeConfig{Enabled: true},
+		HostID:                rac.ResourceAttributeConfig{Enabled: true},
+		HostImageID:           rac.ResourceAttributeConfig{Enabled: true},
+		HostName:              rac.ResourceAttributeConfig{Enabled: true},
+		HostType:              rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"tags":                append([]string{}, args.Tags...),
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config to enable and disable resource attributes.
+type ResourceAttributesConfig struct {
+	CloudAccountID        rac.ResourceAttributeConfig `river:"cloud.account.id,block,optional"`
+	CloudAvailabilityZone rac.ResourceAttributeConfig `river:"cloud.availability_zone,block,optional"`
+	CloudPlatform         rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider         rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+	CloudRegion           rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
+	HostID                rac.ResourceAttributeConfig `river:"host.id,block,optional"`
+	HostImageID           rac.ResourceAttributeConfig `river:"host.image.id,block,optional"`
+	HostName              rac.ResourceAttributeConfig `river:"host.name,block,optional"`
+	HostType              rac.ResourceAttributeConfig `river:"host.type,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"cloud.account.id":        r.CloudAccountID.Convert(),
+		"cloud.availability_zone": r.CloudAvailabilityZone.Convert(),
+		"cloud.platform":          r.CloudPlatform.Convert(),
+		"cloud.provider":          r.CloudProvider.Convert(),
+		"cloud.region":            r.CloudRegion.Convert(),
+		"host.id":                 r.HostID.Convert(),
+		"host.image.id":           r.HostImageID.Convert(),
+		"host.name":               r.HostName.Convert(),
+		"host.type":               r.HostType.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/aws/ecs/config.go b/component/otelcol/processor/resourcedetection/internal/aws/ecs/config.go
new file mode 100644
index 000000000000..1532bd376567
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/aws/ecs/config.go
@@ -0,0 +1,86 @@
+package ecs
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "ecs"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		AwsEcsClusterArn:      rac.ResourceAttributeConfig{Enabled: true},
+		AwsEcsLaunchtype:      rac.ResourceAttributeConfig{Enabled: true},
+		AwsEcsTaskArn:         rac.ResourceAttributeConfig{Enabled: true},
+		AwsEcsTaskFamily:      rac.ResourceAttributeConfig{Enabled: true},
+		AwsEcsTaskRevision:    rac.ResourceAttributeConfig{Enabled: true},
+		AwsLogGroupArns:       rac.ResourceAttributeConfig{Enabled: true},
+		AwsLogGroupNames:      rac.ResourceAttributeConfig{Enabled: true},
+		AwsLogStreamArns:      rac.ResourceAttributeConfig{Enabled: true},
+		AwsLogStreamNames:     rac.ResourceAttributeConfig{Enabled: true},
+		CloudAccountID:        rac.ResourceAttributeConfig{Enabled: true},
+		CloudAvailabilityZone: rac.ResourceAttributeConfig{Enabled: true},
+		CloudPlatform:         rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider:         rac.ResourceAttributeConfig{Enabled: true},
+		CloudRegion:           rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args *Config) Convert() map[string]interface{} {
+	if args == nil {
+		return nil
+	}
+
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for ecs resource attributes.
+type ResourceAttributesConfig struct {
+	AwsEcsClusterArn      rac.ResourceAttributeConfig `river:"aws.ecs.cluster.arn,block,optional"`
+	AwsEcsLaunchtype      rac.ResourceAttributeConfig `river:"aws.ecs.launchtype,block,optional"`
+	AwsEcsTaskArn         rac.ResourceAttributeConfig `river:"aws.ecs.task.arn,block,optional"`
+	AwsEcsTaskFamily      rac.ResourceAttributeConfig `river:"aws.ecs.task.family,block,optional"`
+	AwsEcsTaskRevision    rac.ResourceAttributeConfig `river:"aws.ecs.task.revision,block,optional"`
+	AwsLogGroupArns       rac.ResourceAttributeConfig `river:"aws.log.group.arns,block,optional"`
+	AwsLogGroupNames      rac.ResourceAttributeConfig `river:"aws.log.group.names,block,optional"`
+	AwsLogStreamArns      rac.ResourceAttributeConfig `river:"aws.log.stream.arns,block,optional"`
+	AwsLogStreamNames     rac.ResourceAttributeConfig `river:"aws.log.stream.names,block,optional"`
+	CloudAccountID        rac.ResourceAttributeConfig `river:"cloud.account.id,block,optional"`
+	CloudAvailabilityZone rac.ResourceAttributeConfig `river:"cloud.availability_zone,block,optional"`
+	CloudPlatform         rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider         rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+	CloudRegion           rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"aws.ecs.cluster.arn":     r.AwsEcsClusterArn.Convert(),
+		"aws.ecs.launchtype":      r.AwsEcsLaunchtype.Convert(),
+		"aws.ecs.task.arn":        r.AwsEcsTaskArn.Convert(),
+		"aws.ecs.task.family":     r.AwsEcsTaskFamily.Convert(),
+		"aws.ecs.task.revision":   r.AwsEcsTaskRevision.Convert(),
+		"aws.log.group.arns":      r.AwsLogGroupArns.Convert(),
+		"aws.log.group.names":     r.AwsLogGroupNames.Convert(),
+		"aws.log.stream.arns":     r.AwsLogStreamArns.Convert(),
+		"aws.log.stream.names":    r.AwsLogStreamNames.Convert(),
+		"cloud.account.id":        r.CloudAccountID.Convert(),
+		"cloud.availability_zone": r.CloudAvailabilityZone.Convert(),
+		"cloud.platform":          r.CloudPlatform.Convert(),
+		"cloud.provider":          r.CloudProvider.Convert(),
+		"cloud.region":            r.CloudRegion.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/aws/eks/config.go b/component/otelcol/processor/resourcedetection/internal/aws/eks/config.go
new file mode 100644
index 000000000000..6290180b3086
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/aws/eks/config.go
@@ -0,0 +1,46 @@
+package eks
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "eks"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		CloudPlatform: rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider: rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for eks resource attributes.
+type ResourceAttributesConfig struct {
+	CloudPlatform rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"cloud.platform": r.CloudPlatform.Convert(),
+		"cloud.provider": r.CloudProvider.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/aws/elasticbeanstalk/config.go b/component/otelcol/processor/resourcedetection/internal/aws/elasticbeanstalk/config.go
new file mode 100644
index 000000000000..dd670372cee7
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/aws/elasticbeanstalk/config.go
@@ -0,0 +1,55 @@
+package elasticbeanstalk
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "elasticbeanstalk"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		CloudPlatform:         rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider:         rac.ResourceAttributeConfig{Enabled: true},
+		DeploymentEnvironment: rac.ResourceAttributeConfig{Enabled: true},
+		ServiceInstanceID:     rac.ResourceAttributeConfig{Enabled: true},
+		ServiceVersion:        rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for elastic_beanstalk resource attributes.
+type ResourceAttributesConfig struct {
+	CloudPlatform         rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider         rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+	DeploymentEnvironment rac.ResourceAttributeConfig `river:"deployment.environment,block,optional"`
+	ServiceInstanceID     rac.ResourceAttributeConfig `river:"service.instance.id,block,optional"`
+	ServiceVersion        rac.ResourceAttributeConfig `river:"service.version,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"cloud.platform":         r.CloudPlatform.Convert(),
+		"cloud.provider":         r.CloudProvider.Convert(),
+		"deployment.environment": r.DeploymentEnvironment.Convert(),
+		"service.instance.id":    r.ServiceInstanceID.Convert(),
+		"service.version":        r.ServiceVersion.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/aws/lambda/config.go b/component/otelcol/processor/resourcedetection/internal/aws/lambda/config.go
new file mode 100644
index 000000000000..19a4cc7b4e80
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/aws/lambda/config.go
@@ -0,0 +1,67 @@
+package lambda
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "lambda"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		AwsLogGroupNames:  rac.ResourceAttributeConfig{Enabled: true},
+		AwsLogStreamNames: rac.ResourceAttributeConfig{Enabled: true},
+		CloudPlatform:     rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider:     rac.ResourceAttributeConfig{Enabled: true},
+		CloudRegion:       rac.ResourceAttributeConfig{Enabled: true},
+		FaasInstance:      rac.ResourceAttributeConfig{Enabled: true},
+		FaasMaxMemory:     rac.ResourceAttributeConfig{Enabled: true},
+		FaasName:          rac.ResourceAttributeConfig{Enabled: true},
+		FaasVersion:       rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for lambda resource attributes.
+type ResourceAttributesConfig struct {
+	AwsLogGroupNames  rac.ResourceAttributeConfig `river:"aws.log.group.names,block,optional"`
+	AwsLogStreamNames rac.ResourceAttributeConfig `river:"aws.log.stream.names,block,optional"`
+	CloudPlatform     rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider     rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+	CloudRegion       rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
+	FaasInstance      rac.ResourceAttributeConfig `river:"faas.instance,block,optional"`
+	FaasMaxMemory     rac.ResourceAttributeConfig `river:"faas.max_memory,block,optional"`
+	FaasName          rac.ResourceAttributeConfig `river:"faas.name,block,optional"`
+	FaasVersion       rac.ResourceAttributeConfig `river:"faas.version,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"aws.log.group.names":  r.AwsLogGroupNames.Convert(),
+		"aws.log.stream.names": r.AwsLogStreamNames.Convert(),
+		"cloud.platform":       r.CloudPlatform.Convert(),
+		"cloud.provider":       r.CloudProvider.Convert(),
+		"cloud.region":         r.CloudRegion.Convert(),
+		"faas.instance":        r.FaasInstance.Convert(),
+		"faas.max_memory":      r.FaasMaxMemory.Convert(),
+		"faas.name":            r.FaasName.Convert(),
+		"faas.version":         r.FaasVersion.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/azure/aks/config.go b/component/otelcol/processor/resourcedetection/internal/azure/aks/config.go
new file mode 100644
index 000000000000..4501c4e33a6f
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/azure/aks/config.go
@@ -0,0 +1,46 @@
+package aks
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "aks"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		CloudPlatform: rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider: rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for aks resource attributes.
+type ResourceAttributesConfig struct {
+	CloudPlatform rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"cloud.platform": r.CloudPlatform.Convert(),
+		"cloud.provider": r.CloudProvider.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/azure/config.go b/component/otelcol/processor/resourcedetection/internal/azure/config.go
new file mode 100644
index 000000000000..05e612d1d2d0
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/azure/config.go
@@ -0,0 +1,70 @@
+package azure
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "azure"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		AzureResourcegroupName: rac.ResourceAttributeConfig{Enabled: true},
+		AzureVMName:            rac.ResourceAttributeConfig{Enabled: true},
+		AzureVMScalesetName:    rac.ResourceAttributeConfig{Enabled: true},
+		AzureVMSize:            rac.ResourceAttributeConfig{Enabled: true},
+		CloudAccountID:         rac.ResourceAttributeConfig{Enabled: true},
+		CloudPlatform:          rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider:          rac.ResourceAttributeConfig{Enabled: true},
+		CloudRegion:            rac.ResourceAttributeConfig{Enabled: true},
+		HostID:                 rac.ResourceAttributeConfig{Enabled: true},
+		HostName:               rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for azure resource attributes.
+type ResourceAttributesConfig struct {
+	AzureResourcegroupName rac.ResourceAttributeConfig `river:"azure.resourcegroup.name,block,optional"`
+	AzureVMName            rac.ResourceAttributeConfig `river:"azure.vm.name,block,optional"`
+	AzureVMScalesetName    rac.ResourceAttributeConfig `river:"azure.vm.scaleset.name,block,optional"`
+	AzureVMSize            rac.ResourceAttributeConfig `river:"azure.vm.size,block,optional"`
+	CloudAccountID         rac.ResourceAttributeConfig `river:"cloud.account.id,block,optional"`
+	CloudPlatform          rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider          rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+	CloudRegion            rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
+	HostID                 rac.ResourceAttributeConfig `river:"host.id,block,optional"`
+	HostName               rac.ResourceAttributeConfig `river:"host.name,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"azure.resourcegroup.name": r.AzureResourcegroupName.Convert(),
+		"azure.vm.name":            r.AzureVMName.Convert(),
+		"azure.vm.scaleset.name":   r.AzureVMScalesetName.Convert(),
+		"azure.vm.size":            r.AzureVMSize.Convert(),
+		"cloud.account.id":         r.CloudAccountID.Convert(),
+		"cloud.platform":           r.CloudPlatform.Convert(),
+		"cloud.provider":           r.CloudProvider.Convert(),
+		"cloud.region":             r.CloudRegion.Convert(),
+		"host.id":                  r.HostID.Convert(),
+		"host.name":                r.HostName.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/consul/config.go b/component/otelcol/processor/resourcedetection/internal/consul/config.go
new file mode 100644
index 000000000000..4cc2e9b5beb3
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/consul/config.go
@@ -0,0 +1,94 @@
+package consul
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+	"github.com/grafana/river/rivertypes"
+	"go.opentelemetry.io/collector/config/configopaque"
+)
+
+const Name = "consul"
+
+// The struct requires no user-specified fields by default as consul agent's default
+// configuration will be provided to the API client.
+// See `consul.go#NewDetector` for more information.
+type Config struct {
+	// Address is the address of the Consul server
+	Address string `river:"address,attr,optional"`
+
+	// Datacenter to use. If not provided, the default agent datacenter is used.
+	Datacenter string `river:"datacenter,attr,optional"`
+
+	// Token is used to provide a per-request ACL token which overrides the
+	// agent's default (empty) token. Token is only required if
+	// [Consul's ACL System](https://www.consul.io/docs/security/acl/acl-system)
+	// is enabled.
+	Token rivertypes.Secret `river:"token,attr,optional"`
+
+	// TokenFile is not necessary in River because users can use the local.file
+	// Flow component instead.
+	//
+	// TokenFile string `river:"token_file"`
+
+	// Namespace is the name of the namespace to send along for the request
+	// when no other Namespace is present in the QueryOptions
+	Namespace string `river:"namespace,attr,optional"`
+
+	// Allowlist of [Consul Metadata](https://www.consul.io/docs/agent/options#node_meta)
+	// keys to use as resource attributes.
+	MetaLabels []string `river:"meta,attr,optional"`
+
+	// ResourceAttributes configuration for Consul detector
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		CloudRegion: rac.ResourceAttributeConfig{Enabled: true},
+		HostID:      rac.ResourceAttributeConfig{Enabled: true},
+		HostName:    rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	//TODO(ptodev): Change the OTel Collector's "meta" param to be a slice instead of a map.
+	var metaLabels map[string]string
+	if args.MetaLabels != nil {
+		metaLabels = make(map[string]string, len(args.MetaLabels))
+		for _, label := range args.MetaLabels {
+			metaLabels[label] = ""
+		}
+	}
+
+	return map[string]interface{}{
+		"address":             args.Address,
+		"datacenter":          args.Datacenter,
+		"token":               configopaque.String(args.Token),
+		"namespace":           args.Namespace,
+		"meta":                metaLabels,
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for consul resource attributes.
+type ResourceAttributesConfig struct {
+	CloudRegion rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
+	HostID      rac.ResourceAttributeConfig `river:"host.id,block,optional"`
+	HostName    rac.ResourceAttributeConfig `river:"host.name,block,optional"`
+}
+
+func (r *ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"cloud.region": r.CloudRegion.Convert(),
+		"host.id":      r.HostID.Convert(),
+		"host.name":    r.HostName.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/docker/config.go b/component/otelcol/processor/resourcedetection/internal/docker/config.go
new file mode 100644
index 000000000000..f8c1bdc39b82
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/docker/config.go
@@ -0,0 +1,46 @@
+package docker
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "docker"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		HostName: rac.ResourceAttributeConfig{Enabled: true},
+		OsType:   rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for docker resource attributes.
+type ResourceAttributesConfig struct {
+	HostName rac.ResourceAttributeConfig `river:"host.name,block,optional"`
+	OsType   rac.ResourceAttributeConfig `river:"os.type,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"host.name": r.HostName.Convert(),
+		"os.type":   r.OsType.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/gcp/config.go b/component/otelcol/processor/resourcedetection/internal/gcp/config.go
new file mode 100644
index 000000000000..76395828a97c
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/gcp/config.go
@@ -0,0 +1,91 @@
+package gcp
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "gcp"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		CloudAccountID:          rac.ResourceAttributeConfig{Enabled: true},
+		CloudAvailabilityZone:   rac.ResourceAttributeConfig{Enabled: true},
+		CloudPlatform:           rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider:           rac.ResourceAttributeConfig{Enabled: true},
+		CloudRegion:             rac.ResourceAttributeConfig{Enabled: true},
+		FaasID:                  rac.ResourceAttributeConfig{Enabled: true},
+		FaasInstance:            rac.ResourceAttributeConfig{Enabled: true},
+		FaasName:                rac.ResourceAttributeConfig{Enabled: true},
+		FaasVersion:             rac.ResourceAttributeConfig{Enabled: true},
+		GcpCloudRunJobExecution: rac.ResourceAttributeConfig{Enabled: true},
+		GcpCloudRunJobTaskIndex: rac.ResourceAttributeConfig{Enabled: true},
+		GcpGceInstanceHostname:  rac.ResourceAttributeConfig{Enabled: false},
+		GcpGceInstanceName:      rac.ResourceAttributeConfig{Enabled: false},
+		HostID:                  rac.ResourceAttributeConfig{Enabled: true},
+		HostName:                rac.ResourceAttributeConfig{Enabled: true},
+		HostType:                rac.ResourceAttributeConfig{Enabled: true},
+		K8sClusterName:          rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for gcp resource attributes.
+type ResourceAttributesConfig struct {
+	CloudAccountID          rac.ResourceAttributeConfig `river:"cloud.account.id,block,optional"`
+	CloudAvailabilityZone   rac.ResourceAttributeConfig `river:"cloud.availability_zone,block,optional"`
+	CloudPlatform           rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider           rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+	CloudRegion             rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
+	FaasID                  rac.ResourceAttributeConfig `river:"faas.id,block,optional"`
+	FaasInstance            rac.ResourceAttributeConfig `river:"faas.instance,block,optional"`
+	FaasName                rac.ResourceAttributeConfig `river:"faas.name,block,optional"`
+	FaasVersion             rac.ResourceAttributeConfig `river:"faas.version,block,optional"`
+	GcpCloudRunJobExecution rac.ResourceAttributeConfig `river:"gcp.cloud_run.job.execution,block,optional"`
+	GcpCloudRunJobTaskIndex rac.ResourceAttributeConfig `river:"gcp.cloud_run.job.task_index,block,optional"`
+	GcpGceInstanceHostname  rac.ResourceAttributeConfig `river:"gcp.gce.instance.hostname,block,optional"`
+	GcpGceInstanceName      rac.ResourceAttributeConfig `river:"gcp.gce.instance.name,block,optional"`
+	HostID                  rac.ResourceAttributeConfig `river:"host.id,block,optional"`
+	HostName                rac.ResourceAttributeConfig `river:"host.name,block,optional"`
+	HostType                rac.ResourceAttributeConfig `river:"host.type,block,optional"`
+	K8sClusterName          rac.ResourceAttributeConfig `river:"k8s.cluster.name,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"cloud.account.id":             r.CloudAccountID.Convert(),
+		"cloud.availability_zone":      r.CloudAvailabilityZone.Convert(),
+		"cloud.platform":               r.CloudPlatform.Convert(),
+		"cloud.provider":               r.CloudProvider.Convert(),
+		"cloud.region":                 r.CloudRegion.Convert(),
+		"faas.id":                      r.FaasID.Convert(),
+		"faas.instance":                r.FaasInstance.Convert(),
+		"faas.name":                    r.FaasName.Convert(),
+		"faas.version":                 r.FaasVersion.Convert(),
+		"gcp.cloud_run.job.execution":  r.GcpCloudRunJobExecution.Convert(),
+		"gcp.cloud_run.job.task_index": r.GcpCloudRunJobTaskIndex.Convert(),
+		"gcp.gce.instance.hostname":    r.GcpGceInstanceHostname.Convert(),
+		"gcp.gce.instance.name":        r.GcpGceInstanceName.Convert(),
+		"host.id":                      r.HostID.Convert(),
+		"host.name":                    r.HostName.Convert(),
+		"host.type":                    r.HostType.Convert(),
+		"k8s.cluster.name":             r.K8sClusterName.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/heroku/config.go b/component/otelcol/processor/resourcedetection/internal/heroku/config.go
new file mode 100644
index 000000000000..6e7681269abb
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/heroku/config.go
@@ -0,0 +1,64 @@
+package heroku
+
+import (
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "heroku"
+
+type Config struct {
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		CloudProvider:                  rac.ResourceAttributeConfig{Enabled: true},
+		HerokuAppID:                    rac.ResourceAttributeConfig{Enabled: true},
+		HerokuDynoID:                   rac.ResourceAttributeConfig{Enabled: true},
+		HerokuReleaseCommit:            rac.ResourceAttributeConfig{Enabled: true},
+		HerokuReleaseCreationTimestamp: rac.ResourceAttributeConfig{Enabled: true},
+		ServiceInstanceID:              rac.ResourceAttributeConfig{Enabled: true},
+		ServiceName:                    rac.ResourceAttributeConfig{Enabled: true},
+		ServiceVersion:                 rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for heroku resource attributes.
+type ResourceAttributesConfig struct {
+	CloudProvider                  rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+	HerokuAppID                    rac.ResourceAttributeConfig `river:"heroku.app.id,block,optional"`
+	HerokuDynoID                   rac.ResourceAttributeConfig `river:"heroku.dyno.id,block,optional"`
+	HerokuReleaseCommit            rac.ResourceAttributeConfig `river:"heroku.release.commit,block,optional"`
+	HerokuReleaseCreationTimestamp rac.ResourceAttributeConfig `river:"heroku.release.creation_timestamp,block,optional"`
+	ServiceInstanceID              rac.ResourceAttributeConfig `river:"service.instance.id,block,optional"`
+	ServiceName                    rac.ResourceAttributeConfig `river:"service.name,block,optional"`
+	ServiceVersion                 rac.ResourceAttributeConfig `river:"service.version,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"cloud.provider":                    r.CloudProvider.Convert(),
+		"heroku.app.id":                     r.HerokuAppID.Convert(),
+		"heroku.dyno.id":                    r.HerokuDynoID.Convert(),
+		"heroku.release.commit":             r.HerokuReleaseCommit.Convert(),
+		"heroku.release.creation_timestamp": r.HerokuReleaseCreationTimestamp.Convert(),
+		"service.instance.id":               r.ServiceInstanceID.Convert(),
+		"service.name":                      r.ServiceName.Convert(),
+		"service.version":                   r.ServiceVersion.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/k8snode/config.go b/component/otelcol/processor/resourcedetection/internal/k8snode/config.go
new file mode 100644
index 000000000000..8d47362eecb6
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/k8snode/config.go
@@ -0,0 +1,75 @@
+package k8snode
+
+import (
+	"github.com/grafana/agent/component/otelcol"
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "kubernetes_node"
+
+type Config struct {
+	KubernetesAPIConfig otelcol.KubernetesAPIConfig `river:",squash"`
+	// NodeFromEnv can be used to extract the node name from an environment
+	// variable. The value must be the name of the environment variable.
+	// This is useful when the node where an Agent will run on cannot be
+	// predicted. In such cases, the Kubernetes downward API can be used to
+	// add the node name to each pod as an environment variable. K8s tagger
+	// can then read this value and filter pods by it.
+	//
+	// For example, node name can be passed to each agent with the downward API as follows
+	//
+	// env:
+	//   - name: K8S_NODE_NAME
+	//     valueFrom:
+	//       fieldRef:
+	//         fieldPath: spec.nodeName
+	//
+	// Then the NodeFromEnv field can be set to `K8S_NODE_NAME` to filter all pods by the node that
+	// the agent is running on.
+	//
+	// More on downward API here: https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/
+	NodeFromEnvVar     string                   `river:"node_from_env_var,attr,optional"`
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+var DefaultArguments = Config{
+	KubernetesAPIConfig: otelcol.KubernetesAPIConfig{
+		AuthType: otelcol.KubernetesAPIConfig_AuthType_None,
+	},
+	NodeFromEnvVar: "K8S_NODE_NAME",
+	ResourceAttributes: ResourceAttributesConfig{
+		K8sNodeName: rac.ResourceAttributeConfig{Enabled: true},
+		K8sNodeUID:  rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (c *Config) SetToDefault() {
+	*c = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		//TODO: K8sAPIConfig is squashed - is there a better way to "convert" it?
+		"auth_type":           args.KubernetesAPIConfig.AuthType,
+		"context":             args.KubernetesAPIConfig.Context,
+		"node_from_env_var":   args.NodeFromEnvVar,
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for k8snode resource attributes.
+type ResourceAttributesConfig struct {
+	K8sNodeName rac.ResourceAttributeConfig `river:"k8s.node.name,block,optional"`
+	K8sNodeUID  rac.ResourceAttributeConfig `river:"k8s.node.uid,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"k8s.node.name": r.K8sNodeName.Convert(),
+		"k8s.node.uid":  r.K8sNodeUID.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/openshift/config.go b/component/otelcol/processor/resourcedetection/internal/openshift/config.go
new file mode 100644
index 000000000000..362cd9bff459
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/openshift/config.go
@@ -0,0 +1,68 @@
+package openshift
+
+import (
+	"github.com/grafana/agent/component/otelcol"
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "openshift"
+
+// Config can contain user-specified inputs to overwrite default values.
+// See `openshift.go#NewDetector` for more information.
+type Config struct {
+	// Address is the address of the openshift api server
+	Address string `river:"address,attr,optional"`
+
+	// Token is used to identify against the openshift api server
+	Token string `river:"token,attr,optional"`
+
+	// TLSSettings contains TLS configurations that are specific to client
+	// connection used to communicate with the Openshift API.
+	TLSSettings otelcol.TLSClientArguments `river:"tls,block,optional"`
+
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+// DefaultArguments holds default settings for Config.
+var DefaultArguments = Config{
+	ResourceAttributes: ResourceAttributesConfig{
+		CloudPlatform:  rac.ResourceAttributeConfig{Enabled: true},
+		CloudProvider:  rac.ResourceAttributeConfig{Enabled: true},
+		CloudRegion:    rac.ResourceAttributeConfig{Enabled: true},
+		K8sClusterName: rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (args *Config) SetToDefault() {
+	*args = DefaultArguments
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"address":             args.Address,
+		"token":               args.Token,
+		"tls":                 args.TLSSettings.Convert(),
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for openshift resource attributes.
+type ResourceAttributesConfig struct {
+	CloudPlatform  rac.ResourceAttributeConfig `river:"cloud.platform,block,optional"`
+	CloudProvider  rac.ResourceAttributeConfig `river:"cloud.provider,block,optional"`
+	CloudRegion    rac.ResourceAttributeConfig `river:"cloud.region,block,optional"`
+	K8sClusterName rac.ResourceAttributeConfig `river:"k8s.cluster.name,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"cloud.platform":   r.CloudPlatform.Convert(),
+		"cloud.provider":   r.CloudProvider.Convert(),
+		"cloud.region":     r.CloudRegion.Convert(),
+		"k8s.cluster.name": r.K8sClusterName.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/resource_attribute_config/resource_attribute_config.go b/component/otelcol/processor/resourcedetection/internal/resource_attribute_config/resource_attribute_config.go
new file mode 100644
index 000000000000..ff5540a2f539
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/resource_attribute_config/resource_attribute_config.go
@@ -0,0 +1,12 @@
+package resource_attribute_config
+
+// Configures whether a resource attribute should be enabled or not.
+type ResourceAttributeConfig struct {
+	Enabled bool `river:"enabled,attr"`
+}
+
+func (r ResourceAttributeConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"enabled": r.Enabled,
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/internal/system/config.go b/component/otelcol/processor/resourcedetection/internal/system/config.go
new file mode 100644
index 000000000000..82e25cb45e97
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/internal/system/config.go
@@ -0,0 +1,95 @@
+package system
+
+import (
+	"fmt"
+
+	rac "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/resource_attribute_config"
+	"github.com/grafana/river"
+)
+
+const Name = "system"
+
+// Config defines user-specified configurations unique to the system detector
+type Config struct {
+	// The HostnameSources is a priority list of sources from which hostname will be fetched.
+	// In case of the error in fetching hostname from source,
+	// the next source from the list will be considered.
+	HostnameSources []string `river:"hostname_sources,attr,optional"`
+
+	ResourceAttributes ResourceAttributesConfig `river:"resource_attributes,block,optional"`
+}
+
+var DefaultArguments = Config{
+	HostnameSources: []string{"dns", "os"},
+	ResourceAttributes: ResourceAttributesConfig{
+		HostArch:           rac.ResourceAttributeConfig{Enabled: false},
+		HostCPUCacheL2Size: rac.ResourceAttributeConfig{Enabled: false},
+		HostCPUFamily:      rac.ResourceAttributeConfig{Enabled: false},
+		HostCPUModelID:     rac.ResourceAttributeConfig{Enabled: false},
+		HostCPUModelName:   rac.ResourceAttributeConfig{Enabled: false},
+		HostCPUStepping:    rac.ResourceAttributeConfig{Enabled: false},
+		HostCPUVendorID:    rac.ResourceAttributeConfig{Enabled: false},
+		HostID:             rac.ResourceAttributeConfig{Enabled: false},
+		HostName:           rac.ResourceAttributeConfig{Enabled: true},
+		OsDescription:      rac.ResourceAttributeConfig{Enabled: false},
+		OsType:             rac.ResourceAttributeConfig{Enabled: true},
+	},
+}
+
+var _ river.Defaulter = (*Config)(nil)
+
+// SetToDefault implements river.Defaulter.
+func (c *Config) SetToDefault() {
+	*c = DefaultArguments
+}
+
+// Validate config
+func (cfg *Config) Validate() error {
+	for _, hostnameSource := range cfg.HostnameSources {
+		switch hostnameSource {
+		case "os", "dns", "cname", "lookup":
+			// Valid option - nothing to do
+		default:
+			return fmt.Errorf("invalid hostname source: %s", hostnameSource)
+		}
+	}
+	return nil
+}
+
+func (args Config) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"hostname_sources":    args.HostnameSources,
+		"resource_attributes": args.ResourceAttributes.Convert(),
+	}
+}
+
+// ResourceAttributesConfig provides config for system resource attributes.
+type ResourceAttributesConfig struct {
+	HostArch           rac.ResourceAttributeConfig `river:"host.arch,block,optional"`
+	HostCPUCacheL2Size rac.ResourceAttributeConfig `river:"host.cpu.cache.l2.size,block,optional"`
+	HostCPUFamily      rac.ResourceAttributeConfig `river:"host.cpu.family,block,optional"`
+	HostCPUModelID     rac.ResourceAttributeConfig `river:"host.cpu.model.id,block,optional"`
+	HostCPUModelName   rac.ResourceAttributeConfig `river:"host.cpu.model.name,block,optional"`
+	HostCPUStepping    rac.ResourceAttributeConfig `river:"host.cpu.stepping,block,optional"`
+	HostCPUVendorID    rac.ResourceAttributeConfig `river:"host.cpu.vendor.id,block,optional"`
+	HostID             rac.ResourceAttributeConfig `river:"host.id,block,optional"`
+	HostName           rac.ResourceAttributeConfig `river:"host.name,block,optional"`
+	OsDescription      rac.ResourceAttributeConfig `river:"os.description,block,optional"`
+	OsType             rac.ResourceAttributeConfig `river:"os.type,block,optional"`
+}
+
+func (r ResourceAttributesConfig) Convert() map[string]interface{} {
+	return map[string]interface{}{
+		"host.arch":              r.HostArch.Convert(),
+		"host.cpu.cache.l2.size": r.HostCPUCacheL2Size.Convert(),
+		"host.cpu.family":        r.HostCPUFamily.Convert(),
+		"host.cpu.model.id":      r.HostCPUModelID.Convert(),
+		"host.cpu.model.name":    r.HostCPUModelName.Convert(),
+		"host.cpu.stepping":      r.HostCPUStepping.Convert(),
+		"host.cpu.vendor.id":     r.HostCPUVendorID.Convert(),
+		"host.id":                r.HostID.Convert(),
+		"host.name":              r.HostName.Convert(),
+		"os.description":         r.OsDescription.Convert(),
+		"os.type":                r.OsType.Convert(),
+	}
+}
diff --git a/component/otelcol/processor/resourcedetection/resourcedetection.go b/component/otelcol/processor/resourcedetection/resourcedetection.go
new file mode 100644
index 000000000000..806d72c9d2e5
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/resourcedetection.go
@@ -0,0 +1,247 @@
+package resourcedetection
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/grafana/agent/component"
+	"github.com/grafana/agent/component/otelcol"
+	"github.com/grafana/agent/component/otelcol/processor"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/ec2"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/ecs"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/eks"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/elasticbeanstalk"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/lambda"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/azure"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/azure/aks"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/consul"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/docker"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/gcp"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/heroku"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/k8snode"
+	kubernetes_node "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/k8snode"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/openshift"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/system"
+	"github.com/grafana/river"
+	"github.com/mitchellh/mapstructure"
+	"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor"
+	otelcomponent "go.opentelemetry.io/collector/component"
+	otelextension "go.opentelemetry.io/collector/extension"
+)
+
+func init() {
+	component.Register(component.Registration{
+		Name:    "otelcol.processor.resourcedetection",
+		Args:    Arguments{},
+		Exports: otelcol.ConsumerExports{},
+
+		Build: func(opts component.Options, args component.Arguments) (component.Component, error) {
+			fact := resourcedetectionprocessor.NewFactory()
+			return processor.New(opts, fact, args.(Arguments))
+		},
+	})
+}
+
+// Arguments configures the otelcol.processor.resourcedetection component.
+type Arguments struct {
+	// Detectors is an ordered list of named detectors that should be
+	// run to attempt to detect resource information.
+	Detectors []string `river:"detectors,attr,optional"`
+
+	// Override indicates whether any existing resource attributes
+	// should be overridden or preserved. Defaults to true.
+	Override bool `river:"override,attr,optional"`
+
+	// DetectorConfig is a list of settings specific to all detectors
+	DetectorConfig DetectorConfig `river:",squash"`
+
+	// HTTP client settings for the detector
+	// Timeout default is 5s
+	Timeout time.Duration `river:"timeout,attr,optional"`
+	// Client otelcol.HTTPClientArguments `river:",squash"`
+	//TODO: Uncomment this later, and remove Timeout?
+	//      Can we just get away with a timeout, or do we need all the http client settings?
+	//      It seems that HTTP client settings are only used in the ec2 detection via ClientFromContext.
+	//      This seems like a very niche use case, so for now I won't implement it in the Agent.
+	//      If we do implement it in the Agent, I am not sure how to document the HTTP client settings.
+	//      We'd have to mention that they're only for a very specific use case.
+
+	// Output configures where to send processed data. Required.
+	Output *otelcol.ConsumerArguments `river:"output,block"`
+}
+
+// DetectorConfig contains user-specified configurations unique to all individual detectors
+type DetectorConfig struct {
+	// EC2Config contains user-specified configurations for the EC2 detector
+	EC2Config ec2.Config `river:"ec2,block,optional"`
+
+	// ECSConfig contains user-specified configurations for the ECS detector
+	ECSConfig ecs.Config `river:"ecs,block,optional"`
+
+	// EKSConfig contains user-specified configurations for the EKS detector
+	EKSConfig eks.Config `river:"eks,block,optional"`
+
+	// Elasticbeanstalk contains user-specified configurations for the elasticbeanstalk detector
+	ElasticbeanstalkConfig elasticbeanstalk.Config `river:"elasticbeanstalk,block,optional"`
+
+	// Lambda contains user-specified configurations for the lambda detector
+	LambdaConfig lambda.Config `river:"lambda,block,optional"`
+
+	// Azure contains user-specified configurations for the azure detector
+	AzureConfig azure.Config `river:"azure,block,optional"`
+
+	// Aks contains user-specified configurations for the aks detector
+	AksConfig aks.Config `river:"aks,block,optional"`
+
+	// ConsulConfig contains user-specified configurations for the Consul detector
+	ConsulConfig consul.Config `river:"consul,block,optional"`
+
+	// DockerConfig contains user-specified configurations for the docker detector
+	DockerConfig docker.Config `river:"docker,block,optional"`
+
+	// GcpConfig contains user-specified configurations for the gcp detector
+	GcpConfig gcp.Config `river:"gcp,block,optional"`
+
+	// HerokuConfig contains user-specified configurations for the heroku detector
+	HerokuConfig heroku.Config `river:"heroku,block,optional"`
+
+	// SystemConfig contains user-specified configurations for the System detector
+	SystemConfig system.Config `river:"system,block,optional"`
+
+	// OpenShift contains user-specified configurations for the Openshift detector
+	OpenShiftConfig openshift.Config `river:"openshift,block,optional"`
+
+	// KubernetesNode contains user-specified configurations for the K8SNode detector
+	KubernetesNodeConfig kubernetes_node.Config `river:"kubernetes_node,block,optional"`
+}
+
+var (
+	_ processor.Arguments = Arguments{}
+	_ river.Validator     = (*Arguments)(nil)
+	_ river.Defaulter     = (*Arguments)(nil)
+)
+
+// DefaultArguments holds default settings for Arguments.
+var DefaultArguments = Arguments{
+	Detectors: []string{"env"},
+	Override:  true,
+	Timeout:   5 * time.Second,
+	DetectorConfig: DetectorConfig{
+		EC2Config:              ec2.DefaultArguments,
+		ECSConfig:              ecs.DefaultArguments,
+		EKSConfig:              eks.DefaultArguments,
+		ElasticbeanstalkConfig: elasticbeanstalk.DefaultArguments,
+		LambdaConfig:           lambda.DefaultArguments,
+		AzureConfig:            azure.DefaultArguments,
+		AksConfig:              aks.DefaultArguments,
+		ConsulConfig:           consul.DefaultArguments,
+		DockerConfig:           docker.DefaultArguments,
+		GcpConfig:              gcp.DefaultArguments,
+		HerokuConfig:           heroku.DefaultArguments,
+		SystemConfig:           system.DefaultArguments,
+		OpenShiftConfig:        openshift.DefaultArguments,
+		KubernetesNodeConfig:   kubernetes_node.DefaultArguments,
+	},
+}
+
+// SetToDefault implements river.Defaulter.
+func (args *Arguments) SetToDefault() {
+	*args = DefaultArguments
+}
+
+// Validate implements river.Validator.
+func (args *Arguments) Validate() error {
+	if len(args.Detectors) == 0 {
+		return fmt.Errorf("at least one detector must be specified")
+	}
+
+	for _, detector := range args.Detectors {
+		switch detector {
+		case "env",
+			ec2.Name,
+			ecs.Name,
+			eks.Name,
+			elasticbeanstalk.Name,
+			lambda.Name,
+			azure.Name,
+			aks.Name,
+			consul.Name,
+			docker.Name,
+			gcp.Name,
+			heroku.Name,
+			system.Name,
+			openshift.Name,
+			k8snode.Name:
+		// Valid option - nothing to do
+		default:
+			return fmt.Errorf("invalid detector: %s", detector)
+		}
+	}
+
+	return nil
+}
+
+func (args Arguments) ConvertDetectors() []string {
+	if args.Detectors == nil {
+		return nil
+	}
+
+	res := make([]string, 0, len(args.Detectors))
+	for _, detector := range args.Detectors {
+		switch detector {
+		case k8snode.Name:
+			res = append(res, "k8snode")
+		default:
+			res = append(res, detector)
+		}
+	}
+	return res
+}
+
+// Convert implements processor.Arguments.
+func (args Arguments) Convert() (otelcomponent.Config, error) {
+	input := make(map[string]interface{})
+
+	input["detectors"] = args.ConvertDetectors()
+	input["override"] = args.Override
+	input["timeout"] = args.Timeout
+
+	input["ec2"] = args.DetectorConfig.EC2Config.Convert()
+	input["ecs"] = args.DetectorConfig.ECSConfig.Convert()
+	input["eks"] = args.DetectorConfig.EKSConfig.Convert()
+	input["elasticbeanstalk"] = args.DetectorConfig.ElasticbeanstalkConfig.Convert()
+	input["lambda"] = args.DetectorConfig.LambdaConfig.Convert()
+	input["azure"] = args.DetectorConfig.AzureConfig.Convert()
+	input["aks"] = args.DetectorConfig.AksConfig.Convert()
+	input["consul"] = args.DetectorConfig.ConsulConfig.Convert()
+	input["docker"] = args.DetectorConfig.DockerConfig.Convert()
+	input["gcp"] = args.DetectorConfig.GcpConfig.Convert()
+	input["heroku"] = args.DetectorConfig.HerokuConfig.Convert()
+	input["system"] = args.DetectorConfig.SystemConfig.Convert()
+	input["openshift"] = args.DetectorConfig.OpenShiftConfig.Convert()
+	input["k8snode"] = args.DetectorConfig.KubernetesNodeConfig.Convert()
+
+	var result resourcedetectionprocessor.Config
+	err := mapstructure.Decode(input, &result)
+
+	if err != nil {
+		return nil, err
+	}
+
+	return &result, nil
+}
+
+// Extensions implements processor.Arguments.
+func (args Arguments) Extensions() map[otelcomponent.ID]otelextension.Extension {
+	return nil
+}
+
+// Exporters implements processor.Arguments.
+func (args Arguments) Exporters() map[otelcomponent.DataType]map[otelcomponent.ID]otelcomponent.Component {
+	return nil
+}
+
+// NextConsumers implements processor.Arguments.
+func (args Arguments) NextConsumers() *otelcol.ConsumerArguments {
+	return args.Output
+}
diff --git a/component/otelcol/processor/resourcedetection/resourcedetection_test.go b/component/otelcol/processor/resourcedetection/resourcedetection_test.go
new file mode 100644
index 000000000000..6fbbf0280e06
--- /dev/null
+++ b/component/otelcol/processor/resourcedetection/resourcedetection_test.go
@@ -0,0 +1,1527 @@
+package resourcedetection_test
+
+import (
+	"testing"
+	"time"
+
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/ec2"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/ecs"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/eks"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/elasticbeanstalk"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/aws/lambda"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/azure"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/azure/aks"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/consul"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/docker"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/gcp"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/heroku"
+	kubernetes_node "github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/k8snode"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/openshift"
+	"github.com/grafana/agent/component/otelcol/processor/resourcedetection/internal/system"
+	"github.com/grafana/river"
+	"github.com/mitchellh/mapstructure"
+	"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor"
+	"github.com/stretchr/testify/require"
+)
+
+func TestArguments_UnmarshalRiver(t *testing.T) {
+	tests := []struct {
+		testName string
+		cfg      string
+		expected map[string]interface{}
+		errorMsg string
+	}{
+		{
+			testName: "err_no_detector",
+			cfg: `
+			detectors = []
+			output {}
+			`,
+			errorMsg: "at least one detector must be specified",
+		},
+		{
+			testName: "invalid_detector",
+			cfg: `
+			detectors = ["non-existent-detector"]
+			output {}
+			`,
+			errorMsg: "invalid detector: non-existent-detector",
+		},
+		{
+			testName: "invalid_detector_and_all_valid_ones",
+			cfg: `
+			detectors = ["non-existent-detector2", "env", "ec2", "ecs", "eks", "elasticbeanstalk", "lambda", "azure", "aks", "consul", "docker", "gcp", "heroku", "system", "openshift", "kubernetes_node"]
+			output {}
+			`,
+			errorMsg: "invalid detector: non-existent-detector2",
+		},
+		{
+			testName: "all_detectors_with_defaults",
+			cfg: `
+			detectors = ["env", "ec2", "ecs", "eks", "elasticbeanstalk", "lambda", "azure", "aks", "consul", "docker", "gcp", "heroku", "system", "openshift", "kubernetes_node"]
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"env", "ec2", "ecs", "eks", "elasticbeanstalk", "lambda", "azure", "aks", "consul", "docker", "gcp", "heroku", "system", "openshift", "k8snode"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "default_detector",
+			cfg: `
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"env"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "ec2_defaults",
+			cfg: `
+			detectors = ["ec2"]
+			ec2 {
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"ec2"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"ec2": map[string]interface{}{
+					"tags": []string{},
+					"resource_attributes": map[string]interface{}{
+						"cloud.account.id":        map[string]interface{}{"enabled": true},
+						"cloud.availability_zone": map[string]interface{}{"enabled": true},
+						"cloud.platform":          map[string]interface{}{"enabled": true},
+						"cloud.provider":          map[string]interface{}{"enabled": true},
+						"cloud.region":            map[string]interface{}{"enabled": true},
+						"host.id":                 map[string]interface{}{"enabled": true},
+						"host.image.id":           map[string]interface{}{"enabled": true},
+						"host.name":               map[string]interface{}{"enabled": true},
+						"host.type":               map[string]interface{}{"enabled": true},
+					},
+				},
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "ec2_defaults_empty_resource_attributes",
+			cfg: `
+			detectors = ["ec2"]
+			ec2 {
+				resource_attributes {}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"ec2"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"ec2": map[string]interface{}{
+					"tags": []string{},
+					"resource_attributes": map[string]interface{}{
+						"cloud.account.id":        map[string]interface{}{"enabled": true},
+						"cloud.availability_zone": map[string]interface{}{"enabled": true},
+						"cloud.platform":          map[string]interface{}{"enabled": true},
+						"cloud.provider":          map[string]interface{}{"enabled": true},
+						"cloud.region":            map[string]interface{}{"enabled": true},
+						"host.id":                 map[string]interface{}{"enabled": true},
+						"host.image.id":           map[string]interface{}{"enabled": true},
+						"host.name":               map[string]interface{}{"enabled": true},
+						"host.type":               map[string]interface{}{"enabled": true},
+					},
+				},
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "ec2_explicit",
+			cfg: `
+			detectors = ["ec2"]
+			ec2 {
+				tags = ["^tag1$", "^tag2$", "^label.*$"]
+				resource_attributes {
+					cloud.account.id  { enabled = true }
+					cloud.availability_zone  { enabled = true }
+					cloud.platform  { enabled = true }
+					cloud.provider  { enabled = true }
+					cloud.region  { enabled = true }
+					host.id  { enabled = true }
+					host.image.id  { enabled = false }
+					host.name  { enabled = false }
+					host.type  { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"ec2"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"ec2": map[string]interface{}{
+					"tags": []string{"^tag1$", "^tag2$", "^label.*$"},
+					"resource_attributes": map[string]interface{}{
+						"cloud.account.id":        map[string]interface{}{"enabled": true},
+						"cloud.availability_zone": map[string]interface{}{"enabled": true},
+						"cloud.platform":          map[string]interface{}{"enabled": true},
+						"cloud.provider":          map[string]interface{}{"enabled": true},
+						"cloud.region":            map[string]interface{}{"enabled": true},
+						"host.id":                 map[string]interface{}{"enabled": true},
+						"host.image.id":           map[string]interface{}{"enabled": false},
+						"host.name":               map[string]interface{}{"enabled": false},
+						"host.type":               map[string]interface{}{"enabled": false},
+					},
+				},
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "ecs_defaults",
+			cfg: `
+			detectors = ["ecs"]
+			ecs {
+				resource_attributes {
+					aws.ecs.cluster.arn  { enabled = true }
+					aws.ecs.launchtype  { enabled = true }
+					aws.ecs.task.arn  { enabled = true }
+					aws.ecs.task.family  { enabled = true }
+					aws.ecs.task.revision  { enabled = true }
+					aws.log.group.arns  { enabled = true }
+					aws.log.group.names  { enabled = false }
+					// aws.log.stream.arns  { enabled = true }
+					// aws.log.stream.names  { enabled = true }
+					// cloud.account.id  { enabled = true }
+					// cloud.availability_zone  { enabled = true }
+					// cloud.platform  { enabled = true }
+					// cloud.provider  { enabled = true }
+					// cloud.region  { enabled = true }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"ecs"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"ecs": map[string]interface{}{
+					"tags": []string{},
+					"resource_attributes": map[string]interface{}{
+						"aws.ecs.cluster.arn":     map[string]interface{}{"enabled": true},
+						"aws.ecs.launchtype":      map[string]interface{}{"enabled": true},
+						"aws.ecs.task.arn":        map[string]interface{}{"enabled": true},
+						"aws.ecs.task.family":     map[string]interface{}{"enabled": true},
+						"aws.ecs.task.revision":   map[string]interface{}{"enabled": true},
+						"aws.log.group.arns":      map[string]interface{}{"enabled": true},
+						"aws.log.group.names":     map[string]interface{}{"enabled": false},
+						"aws.log.stream.arns":     map[string]interface{}{"enabled": true},
+						"aws.log.stream.names":    map[string]interface{}{"enabled": true},
+						"cloud.account.id":        map[string]interface{}{"enabled": true},
+						"cloud.availability_zone": map[string]interface{}{"enabled": true},
+						"cloud.platform":          map[string]interface{}{"enabled": true},
+						"cloud.provider":          map[string]interface{}{"enabled": true},
+						"cloud.region":            map[string]interface{}{"enabled": true},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "ecs_explicit",
+			cfg: `
+			detectors = ["ecs"]
+			ecs {
+				resource_attributes {
+					aws.ecs.cluster.arn  { enabled = true }
+					aws.ecs.launchtype  { enabled = true }
+					aws.ecs.task.arn  { enabled = true }
+					aws.ecs.task.family  { enabled = true }
+					aws.ecs.task.revision  { enabled = true }
+					aws.log.group.arns  { enabled = true }
+					aws.log.group.names  { enabled = false }
+					// aws.log.stream.arns  { enabled = true }
+					// aws.log.stream.names  { enabled = true }
+					// cloud.account.id  { enabled = true }
+					// cloud.availability_zone  { enabled = true }
+					// cloud.platform  { enabled = true }
+					// cloud.provider  { enabled = true }
+					// cloud.region  { enabled = true }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"ecs"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"ecs": map[string]interface{}{
+					"tags": []string{},
+					"resource_attributes": map[string]interface{}{
+						"aws.ecs.cluster.arn":     map[string]interface{}{"enabled": true},
+						"aws.ecs.launchtype":      map[string]interface{}{"enabled": true},
+						"aws.ecs.task.arn":        map[string]interface{}{"enabled": true},
+						"aws.ecs.task.family":     map[string]interface{}{"enabled": true},
+						"aws.ecs.task.revision":   map[string]interface{}{"enabled": true},
+						"aws.log.group.arns":      map[string]interface{}{"enabled": true},
+						"aws.log.group.names":     map[string]interface{}{"enabled": false},
+						"aws.log.stream.arns":     map[string]interface{}{"enabled": true},
+						"aws.log.stream.names":    map[string]interface{}{"enabled": true},
+						"cloud.account.id":        map[string]interface{}{"enabled": true},
+						"cloud.availability_zone": map[string]interface{}{"enabled": true},
+						"cloud.platform":          map[string]interface{}{"enabled": true},
+						"cloud.provider":          map[string]interface{}{"enabled": true},
+						"cloud.region":            map[string]interface{}{"enabled": true},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "eks_defaults",
+			cfg: `
+			detectors = ["eks"]
+			eks {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"eks"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"eks": map[string]interface{}{
+					"tags": []string{},
+					"resource_attributes": map[string]interface{}{
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "eks_explicit",
+			cfg: `
+			detectors = ["eks"]
+			eks {
+				resource_attributes {
+					cloud.platform { enabled = true }
+					cloud.provider { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"eks"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"eks": map[string]interface{}{
+					"tags": []string{},
+					"resource_attributes": map[string]interface{}{
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": false,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "azure_defaults",
+			cfg: `
+			detectors = ["azure"]
+			azure {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"azure"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"azure": map[string]interface{}{
+					"resource_attributes": map[string]interface{}{
+						"tags": []string{},
+						"azure.resourcegroup.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"azure.vm.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"azure.vm.scaleset.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"azure.vm.size": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.account.id": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.region": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.id": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.name": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "azure_explicit",
+			cfg: `
+			detectors = ["azure"]
+			azure {
+				resource_attributes {
+					azure.resourcegroup.name { enabled = true }
+					azure.vm.name { enabled = true }
+					azure.vm.scaleset.name { enabled = true }
+					azure.vm.size { enabled = true }
+					cloud.account.id { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"azure"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"azure": map[string]interface{}{
+					"resource_attributes": map[string]interface{}{
+						"tags": []string{},
+						"azure.resourcegroup.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"azure.vm.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"azure.vm.scaleset.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"azure.vm.size": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.account.id": map[string]interface{}{
+							"enabled": false,
+						},
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.region": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.id": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.name": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "aks_defaults",
+			cfg: `
+			detectors = ["aks"]
+			aks {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"aks"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"aks": map[string]interface{}{
+					"tags": []string{},
+					"resource_attributes": map[string]interface{}{
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "aks_explicit",
+			cfg: `
+			detectors = ["aks"]
+			aks {
+				resource_attributes {
+					cloud.platform { enabled = true }
+					cloud.provider { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"aks"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"aks": map[string]interface{}{
+					"tags": []string{},
+					"resource_attributes": map[string]interface{}{
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": false,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "gcp_defaults",
+			cfg: `
+			detectors = ["gcp"]
+			gcp {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"gcp"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "gcp_explicit",
+			cfg: `
+			detectors = ["gcp"]
+			gcp {
+				resource_attributes {
+					cloud.account.id { enabled = true }
+					cloud.availability_zone { enabled = true }
+					cloud.platform { enabled = true }
+					cloud.provider { enabled = true }
+					cloud.region { enabled = false }
+					faas.id { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"gcp"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"gcp": map[string]interface{}{
+					"resource_attributes": map[string]interface{}{
+						"cloud.account.id": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.availability_zone": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.region": map[string]interface{}{
+							"enabled": false,
+						},
+						"faas.id": map[string]interface{}{
+							"enabled": false,
+						},
+						"faas.instance": map[string]interface{}{
+							"enabled": true,
+						},
+						"faas.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"faas.version": map[string]interface{}{
+							"enabled": true,
+						},
+						"gcp.cloud_run.job.execution": map[string]interface{}{
+							"enabled": true,
+						},
+						"gcp.cloud_run.job.task_index": map[string]interface{}{
+							"enabled": true,
+						},
+						"gcp.gce.instance.hostname": map[string]interface{}{
+							"enabled": false,
+						},
+						"gcp.gce.instance.name": map[string]interface{}{
+							"enabled": false,
+						},
+						"host.id": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.type": map[string]interface{}{
+							"enabled": true,
+						},
+						"k8s.cluster.name": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "docker_defaults",
+			cfg: `
+			detectors = ["docker"]
+			docker {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"docker"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "docker_explicit",
+			cfg: `
+			detectors = ["docker"]
+			docker {
+				resource_attributes {
+					host.name { enabled = true }
+					os.type { enabled = false }
+
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"docker"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"docker": map[string]interface{}{
+					"resource_attributes": map[string]interface{}{
+						"host.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"os.type": map[string]interface{}{
+							"enabled": false,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "lambda_defaults",
+			cfg: `
+			detectors = ["lambda"]
+			lambda {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"lambda"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "lambda_explicit",
+			cfg: `
+			detectors = ["lambda"]
+			lambda {
+				resource_attributes {
+					aws.log.group.names { enabled = true }
+					aws.log.stream.names { enabled = true }
+					cloud.platform { enabled = true }
+					cloud.provider { enabled = false }
+					cloud.region { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"lambda"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"lambda": map[string]interface{}{
+					"resource_attributes": map[string]interface{}{
+						"aws.log.group.names": map[string]interface{}{
+							"enabled": true,
+						},
+						"aws.log.stream.names": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": false,
+						},
+						"cloud.region": map[string]interface{}{
+							"enabled": false,
+						},
+						"faas.instance": map[string]interface{}{
+							"enabled": true,
+						},
+						"faas.max_memory": map[string]interface{}{
+							"enabled": true,
+						},
+						"faas.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"faas.version": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "elasticbeanstalk_defaults",
+			cfg: `
+			detectors = ["elasticbeanstalk"]
+			elasticbeanstalk {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"elasticbeanstalk"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "elasticbeanstalk_explicit",
+			cfg: `
+			detectors = ["elasticbeanstalk"]
+			elasticbeanstalk {
+				resource_attributes {
+					cloud.platform { enabled = true }
+					cloud.provider { enabled = true }
+					deployment.environment { enabled = true }
+					service.instance.id { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"elasticbeanstalk"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"elasticbeanstalk": map[string]interface{}{
+					"resource_attributes": map[string]interface{}{
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": true,
+						},
+						"deployment.environment": map[string]interface{}{
+							"enabled": true,
+						},
+						"service.instance.id": map[string]interface{}{
+							"enabled": false,
+						},
+						"service.version": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":       ec2.DefaultArguments.Convert(),
+				"ecs":       ecs.DefaultArguments.Convert(),
+				"eks":       eks.DefaultArguments.Convert(),
+				"lambda":    lambda.DefaultArguments.Convert(),
+				"azure":     azure.DefaultArguments.Convert(),
+				"aks":       aks.DefaultArguments.Convert(),
+				"consul":    consul.DefaultArguments.Convert(),
+				"docker":    docker.DefaultArguments.Convert(),
+				"gcp":       gcp.DefaultArguments.Convert(),
+				"heroku":    heroku.DefaultArguments.Convert(),
+				"system":    system.DefaultArguments.Convert(),
+				"openshift": openshift.DefaultArguments.Convert(),
+				"k8snode":   kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "consul_defaults",
+			cfg: `
+			detectors = ["consul"]
+			consul {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"consul"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "consul_explicit",
+			cfg: `
+			detectors = ["consul"]
+			consul {
+				address = "localhost:8500"
+				datacenter = "dc1"
+				token = "secret_token"
+				namespace = "test_namespace"
+				meta = ["test"]
+				resource_attributes {
+					cloud.region { enabled = false }
+					host.id { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"consul"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"consul": map[string]interface{}{
+					"address":    "localhost:8500",
+					"datacenter": "dc1",
+					"token":      "secret_token",
+					"namespace":  "test_namespace",
+					"meta":       map[string]string{"test": ""},
+					"resource_attributes": map[string]interface{}{
+						"cloud.region": map[string]interface{}{
+							"enabled": false,
+						},
+						"host.id": map[string]interface{}{
+							"enabled": false,
+						},
+						"host.name": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "heroku_defaults",
+			cfg: `
+			detectors = ["heroku"]
+			heroku {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"heroku"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "heroku_explicit",
+			cfg: `
+			detectors = ["heroku"]
+			heroku {
+				resource_attributes {
+					cloud.provider { enabled = true }
+					heroku.app.id { enabled = true }
+					heroku.dyno.id { enabled = true }
+					heroku.release.commit { enabled = true }
+					heroku.release.creation_timestamp { enabled = false }
+					service.instance.id { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"heroku"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"heroku": map[string]interface{}{
+					"resource_attributes": map[string]interface{}{
+						"cloud.provider": map[string]interface{}{
+							"enabled": true,
+						},
+						"heroku.app.id": map[string]interface{}{
+							"enabled": true,
+						},
+						"heroku.dyno.id": map[string]interface{}{
+							"enabled": true,
+						},
+						"heroku.release.commit": map[string]interface{}{
+							"enabled": true,
+						},
+						"heroku.release.creation_timestamp": map[string]interface{}{
+							"enabled": false,
+						},
+						"service.instance.id": map[string]interface{}{
+							"enabled": false,
+						},
+						"service.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"service.version": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "kubernetes_node_defaults",
+			cfg: `
+			detectors = ["kubernetes_node"]
+			kubernetes_node {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"k8snode"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "kubernetes_node_explicit",
+			cfg: `
+			detectors = ["kubernetes_node"]
+			kubernetes_node {
+				auth_type = "kubeConfig"
+				context = "fake_ctx"
+				node_from_env_var = "MY_CUSTOM_VAR"
+				resource_attributes {
+					k8s.node.name { enabled = true }
+					k8s.node.uid { enabled = false }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"k8snode"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"k8snode": map[string]interface{}{
+					"auth_type":         "kubeConfig",
+					"context":           "fake_ctx",
+					"node_from_env_var": "MY_CUSTOM_VAR",
+					"resource_attributes": map[string]interface{}{
+						"k8s.node.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"k8s.node.uid": map[string]interface{}{
+							"enabled": false,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "system_invalid_hostname_source",
+			cfg: `
+			detectors = ["system"]
+			system {
+				hostname_sources = ["asdf"]
+				resource_attributes { }
+			}
+			output {}
+			`,
+			errorMsg: "invalid hostname source: asdf",
+		},
+		{
+			testName: "system_defaults",
+			cfg: `
+			detectors = ["system"]
+			system {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"system"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "system_explicit",
+			cfg: `
+			detectors = ["system"]
+			system {
+				hostname_sources = ["cname","lookup"]
+				resource_attributes {
+					host.arch { enabled = true }
+					host.cpu.cache.l2.size { enabled = true }
+					host.cpu.family { enabled = true }
+					host.cpu.model.id { enabled = true }
+					host.cpu.model.name { enabled = true }
+					host.cpu.stepping { enabled = true }
+					host.cpu.vendor.id { enabled = false }
+					host.id { enabled = false }
+					host.name { enabled = false }
+					// os.description { enabled = false }
+					// os.type { enabled = true }
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"system"},
+				"timeout":   5 * time.Second,
+				"override":  true,
+				"system": map[string]interface{}{
+					"hostname_sources": []string{"cname", "lookup"},
+					"resource_attributes": map[string]interface{}{
+						"host.arch": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.cpu.cache.l2.size": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.cpu.family": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.cpu.model.id": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.cpu.model.name": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.cpu.stepping": map[string]interface{}{
+							"enabled": true,
+						},
+						"host.cpu.vendor.id": map[string]interface{}{
+							"enabled": false,
+						},
+						"host.id": map[string]interface{}{
+							"enabled": false,
+						},
+						"host.name": map[string]interface{}{
+							"enabled": false,
+						},
+						"os.description": map[string]interface{}{
+							"enabled": false,
+						},
+						"os.type": map[string]interface{}{
+							"enabled": true,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "openshift_default",
+			cfg: `
+			detectors = ["openshift"]
+			openshift {}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"openshift"},
+				"timeout":          5 * time.Second,
+				"override":         true,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "openshift_explicit",
+			cfg: `
+			detectors = ["openshift"]
+			timeout = "7s"
+			override = false
+			openshift {
+				address = "127.0.0.1:4444"
+				token = "some_token"
+				tls {
+					insecure = true
+				}
+				resource_attributes {
+					cloud.platform {
+						enabled = true
+					}
+					cloud.provider {
+						enabled = true
+					}
+					cloud.region {
+						enabled = false
+					}
+					k8s.cluster.name {
+						enabled = false
+					}
+				}
+			}
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors": []string{"openshift"},
+				"timeout":   7 * time.Second,
+				"override":  false,
+				"openshift": map[string]interface{}{
+					"address": "127.0.0.1:4444",
+					"token":   "some_token",
+					"tls": map[string]interface{}{
+						"insecure": true,
+					},
+					"resource_attributes": map[string]interface{}{
+						"cloud.platform": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.provider": map[string]interface{}{
+							"enabled": true,
+						},
+						"cloud.region": map[string]interface{}{
+							"enabled": false,
+						},
+						"k8s.cluster.name": map[string]interface{}{
+							"enabled": false,
+						},
+					},
+				},
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+		{
+			testName: "env",
+			cfg: `
+			detectors = ["env"]
+			timeout = "7s"
+			override = false
+			output {}
+			`,
+			expected: map[string]interface{}{
+				"detectors":        []string{"env"},
+				"timeout":          7 * time.Second,
+				"override":         false,
+				"ec2":              ec2.DefaultArguments.Convert(),
+				"ecs":              ecs.DefaultArguments.Convert(),
+				"eks":              eks.DefaultArguments.Convert(),
+				"elasticbeanstalk": elasticbeanstalk.DefaultArguments.Convert(),
+				"lambda":           lambda.DefaultArguments.Convert(),
+				"azure":            azure.DefaultArguments.Convert(),
+				"aks":              aks.DefaultArguments.Convert(),
+				"consul":           consul.DefaultArguments.Convert(),
+				"docker":           docker.DefaultArguments.Convert(),
+				"gcp":              gcp.DefaultArguments.Convert(),
+				"heroku":           heroku.DefaultArguments.Convert(),
+				"system":           system.DefaultArguments.Convert(),
+				"openshift":        openshift.DefaultArguments.Convert(),
+				"k8snode":          kubernetes_node.DefaultArguments.Convert(),
+			},
+		},
+	}
+
+	for _, tc := range tests {
+		t.Run(tc.testName, func(t *testing.T) {
+			var args resourcedetection.Arguments
+			err := river.Unmarshal([]byte(tc.cfg), &args)
+			if tc.errorMsg != "" {
+				require.ErrorContains(t, err, tc.errorMsg)
+				return
+			}
+
+			require.NoError(t, err)
+
+			actualPtr, err := args.Convert()
+			require.NoError(t, err)
+
+			actual := actualPtr.(*resourcedetectionprocessor.Config)
+
+			var expected resourcedetectionprocessor.Config
+			err = mapstructure.Decode(tc.expected, &expected)
+			require.NoError(t, err)
+
+			require.Equal(t, expected, *actual)
+		})
+	}
+}
diff --git a/docs/sources/flow/reference/compatibility/_index.md b/docs/sources/flow/reference/compatibility/_index.md
index 633433ef6768..44a9c5382a28 100644
--- a/docs/sources/flow/reference/compatibility/_index.md
+++ b/docs/sources/flow/reference/compatibility/_index.md
@@ -298,6 +298,7 @@ The following components, grouped by namespace, _export_ OpenTelemetry `otelcol.
 - [otelcol.processor.k8sattributes]({{< relref "../components/otelcol.processor.k8sattributes.md" >}})
 - [otelcol.processor.memory_limiter]({{< relref "../components/otelcol.processor.memory_limiter.md" >}})
 - [otelcol.processor.probabilistic_sampler]({{< relref "../components/otelcol.processor.probabilistic_sampler.md" >}})
+- [otelcol.processor.resourcedetection]({{< relref "../components/otelcol.processor.resourcedetection.md" >}})
 - [otelcol.processor.span]({{< relref "../components/otelcol.processor.span.md" >}})
 - [otelcol.processor.tail_sampling]({{< relref "../components/otelcol.processor.tail_sampling.md" >}})
 - [otelcol.processor.transform]({{< relref "../components/otelcol.processor.transform.md" >}})
@@ -326,6 +327,7 @@ The following components, grouped by namespace, _consume_ OpenTelemetry `otelcol
 - [otelcol.processor.k8sattributes]({{< relref "../components/otelcol.processor.k8sattributes.md" >}})
 - [otelcol.processor.memory_limiter]({{< relref "../components/otelcol.processor.memory_limiter.md" >}})
 - [otelcol.processor.probabilistic_sampler]({{< relref "../components/otelcol.processor.probabilistic_sampler.md" >}})
+- [otelcol.processor.resourcedetection]({{< relref "../components/otelcol.processor.resourcedetection.md" >}})
 - [otelcol.processor.span]({{< relref "../components/otelcol.processor.span.md" >}})
 - [otelcol.processor.tail_sampling]({{< relref "../components/otelcol.processor.tail_sampling.md" >}})
 - [otelcol.processor.transform]({{< relref "../components/otelcol.processor.transform.md" >}})
diff --git a/docs/sources/flow/reference/components/otelcol.processor.resourcedetection.md b/docs/sources/flow/reference/components/otelcol.processor.resourcedetection.md
new file mode 100644
index 000000000000..204372aa8d6e
--- /dev/null
+++ b/docs/sources/flow/reference/components/otelcol.processor.resourcedetection.md
@@ -0,0 +1,933 @@
+---
+aliases:
+- /docs/grafana-cloud/agent/flow/reference/components/otelcol.processor.resourcedetection/
+- /docs/grafana-cloud/monitor-infrastructure/agent/flow/reference/components/otelcol.processor.resourcedetection/
+- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/reference/components/otelcol.processor.resourcedetection/
+- /docs/grafana-cloud/send-data/agent/flow/reference/components/otelcol.processor.resourcedetection/
+canonical: https://grafana.com/docs/agent/latest/flow/reference/components/otelcol.processor.resourcedetection/
+labels:
+  stage: beta
+title: otelcol.processor.resourcedetection
+description: Learn about otelcol.processor.resourcedetection
+---
+
+# otelcol.processor.resourcedetection
+
+{{< docs/shared lookup="flow/stability/beta.md" source="agent" version="<AGENT VERSION>" >}}
+
+`otelcol.processor.resourcedetection` detects resource information from the host
+in a format that conforms to the [OpenTelemetry resource semantic conventions](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions/), and appends or
+overrides the resource values in the telemetry data with this information.
+
+{{% admonition type="note" %}}
+`otelcol.processor.resourcedetection` is a wrapper over the upstream
+OpenTelemetry Collector Contrib `resourcedetection` processor. If necessary, 
+bug reports or feature requests are redirected to the upstream repository.
+{{% /admonition %}}
+
+You can specify multiple `otelcol.processor.resourcedetection` components by giving them
+different labels.
+
+## Usage
+
+```river
+otelcol.processor.resourcedetection "LABEL" {
+  output {
+    logs    = [...]
+    metrics = [...]
+    traces  = [...]
+  }
+}
+```
+
+## Arguments
+
+`otelcol.processor.resourcedetection` supports the following arguments:
+
+Name        | Type           | Description                                                                         | Default   | Required
+----------- | -------------- | ----------------------------------------------------------------------------------- |---------- | --------
+`detectors` | `list(string)` | An ordered list of named detectors used to detect resource information.             | `["env"]` | no
+`override`  | `bool`         | Configures whether existing resource attributes should be overridden or preserved.  | `true`    | no
+`timeout`   | `duration`     | Timeout by which all specified detectors must complete.                             | `"5s"`    | no
+
+`detectors` could contain the following values:
+* `env`
+* `ec2`
+* `ecs`
+* `eks`
+* `elasticbeanstalk`
+* `lambda`
+* `azure`
+* `aks`
+* `consul`
+* `docker`
+* `gcp`
+* `heroku`
+* `system`
+* `openshift`
+* `kubernetes_node`
+
+`env` is the only detector that is not configured through a River block.
+The `env` detector reads resource information from the `OTEL_RESOURCE_ATTRIBUTES` environment variable. 
+This variable must be in the format `<key1>=<value1>,<key2>=<value2>,...`, 
+the details of which are currently pending confirmation in the OpenTelemetry specification.
+
+If a detector other than `env` is needed, you can customize it with the relevant River block.
+For example, you can customize the `ec2` detector with the [ec2][] block.
+If you omit the [ec2][] block, the defaults specified in the [ec2][] block documentation are used.
+
+If multiple detectors are inserting the same attribute name, the first detector to insert wins. 
+For example, if you had `detectors = ["eks", "ec2"]` then `cloud.platform` will be `aws_eks` instead of `ec2`. 
+
+The following order is recommended for AWS:
+  1. [lambda][]
+  1. [elasticbeanstalk][]
+  1. [eks][]
+  1. [ecs][]
+  1. [ec2][]
+
+## Blocks
+
+The following blocks are supported inside the definition of `otelcol.processor.resourcedetection`:
+
+Hierarchy         | Block                 | Description                                       | Required
+----------------- | --------------------- | ------------------------------------------------- | --------
+output            | [output][]            | Configures where to send received telemetry data. | yes
+ec2               | [ec2][]               |                                                   | no
+ecs               | [ecs][]               |                                                   | no
+eks               | [eks][]               |                                                   | no
+elasticbeanstalk  | [elasticbeanstalk][]  |                                                   | no
+lambda            | [lambda][]            |                                                   | no
+azure             | [azure][]             |                                                   | no
+aks               | [aks][]               |                                                   | no
+consul            | [consul][]            |                                                   | no
+docker            | [docker][]            |                                                   | no
+gcp               | [gcp][]               |                                                   | no
+heroku            | [heroku][]            |                                                   | no
+system            | [system][]            |                                                   | no
+openshift         | [openshift][]         |                                                   | no
+kubernetes_node   | [kubernetes_node][]   |                                                   | no
+
+[output]: #output
+[ec2]: #ec2
+[ecs]: #ecs
+[eks]: #eks
+[elasticbeanstalk]: #elasticbeanstalk
+[lambda]: #lambda
+[azure]: #azure
+[aks]: #aks
+[consul]: #consul
+[docker]: #docker
+[gcp]: #gcp
+[heroku]: #heroku
+[system]: #system
+[openshift]: #openshift
+[kubernetes_node]: #kubernetes_node
+
+[res-attr-cfg]: #resource-attribute-config
+
+### output
+
+{{< docs/shared lookup="flow/reference/components/output-block.md" source="agent" version="<AGENT VERSION>" >}}
+
+### ec2
+
+The `ec2` block reads resource information from the [EC2 instance metadata API] using the [AWS SDK for Go][].
+
+The `ec2` block supports the following attributes:
+
+Attribute   | Type           | Description                                                                 | Default     | Required
+----------- |----------------| --------------------------------------------------------------------------- |-------------| --------
+`tags`      | `list(string)` | A list of regular expressions to match against tag keys of an EC2 instance. | `[]`        | no
+
+If you are using a proxy server on your EC2 instance, it's important that you exempt requests for instance metadata as described in the [AWS cli user guide][]. 
+Failing to do so can result in proxied or missing instance data.
+
+If the instance is part of AWS ParallelCluster and the detector is failing to connect to the metadata server, 
+check the iptable and make sure the chain `PARALLELCLUSTER_IMDS` contains a rule that allows the {{< param "PRODUCT_ROOT_NAME" >}} user to access `169.254.169.254/32`.
+
+[AWS SDK for Go]: https://docs.aws.amazon.com/sdk-for-go/api/aws/ec2metadata/
+[EC2 instance metadata API]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
+[AWS cli user guide]: https://github.com/awsdocs/aws-cli-user-guide/blob/a2393582590b64bd2a1d9978af15b350e1f9eb8e/doc_source/cli-configure-proxy.md#using-a-proxy-on-amazon-ec2-instances
+
+`tags` can be used to gather tags for the EC2 instance which {{< param "PRODUCT_ROOT_NAME" >}} is running on. 
+To fetch EC2 tags, the IAM role assigned to the EC2 instance must have a policy that includes the `ec2:DescribeTags` permission.
+
+The `ec2` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#ec2--resource_attributes) | Configures which resource attributes to add.      | no
+
+##### ec2 > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                   | Description                                                                                         | Required
+--------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[cloud.account.id][res-attr-cfg]        | Toggles the `cloud.account.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.availability_zone][res-attr-cfg] | Toggles the `cloud.availability_zone` resource attribute. <br> Sets `enabled` to `true` by default. | no
+[cloud.platform][res-attr-cfg]          | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.          | no
+[cloud.provider][res-attr-cfg]          | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.          | no
+[cloud.region][res-attr-cfg]            | Toggles the `cloud.region` resource attribute. <br> Sets `enabled` to `true` by default.            | no
+[host.id][res-attr-cfg]                 | Toggles the `host.id` resource attribute. <br> Sets `enabled` to `true` by default.                 | no
+[host.image.id][res-attr-cfg]           | Toggles the `host.image.id` resource attribute. <br> Sets `enabled` to `true` by default.           | no
+[host.name][res-attr-cfg]               | Toggles the `host.name` resource attribute. <br> Sets `enabled` to `true` by default.               | no
+[host.type][res-attr-cfg]               | Toggles the `host.type` resource attribute. <br> Sets `enabled` to `true` by default.               | no
+
+### ecs
+
+The `ecs` block queries the Task Metadata Endpoint (TMDE) to record information about the current ECS Task. Only TMDE V4 and V3 are supported.
+
+[Task Metadata Endpoint]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint.html
+
+The `ecs` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#ecs--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### ecs > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                   | Description                                                                                         | Required
+--------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[aws.ecs.cluster.arn][res-attr-cfg]     | Toggles the `aws.ecs.cluster.arn` resource attribute. <br> Sets `enabled` to `true` by default.     | no
+[aws.ecs.launchtype][res-attr-cfg]      | Toggles the `aws.ecs.launchtype` resource attribute. <br> Sets `enabled` to `true` by default.      | no
+[aws.ecs.task.arn][res-attr-cfg]        | Toggles the `aws.ecs.task.arn` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[aws.ecs.task.family][res-attr-cfg]     | Toggles the `aws.ecs.task.family` resource attribute. <br> Sets `enabled` to `true` by default.     | no
+[aws.ecs.task.revision][res-attr-cfg]   | Toggles the `aws.ecs.task.revision` resource attribute. <br> Sets `enabled` to `true` by default.   | no
+[aws.log.group.arns][res-attr-cfg]      | Toggles the `aws.log.group.arns` resource attribute. <br> Sets `enabled` to `true` by default.      | no
+[aws.log.group.names][res-attr-cfg]     | Toggles the `aws.log.group.names` resource attribute. <br> Sets `enabled` to `true` by default.     | no
+[aws.log.stream.arns][res-attr-cfg]     | Toggles the `aws.log.stream.arns` resource attribute. <br> Sets `enabled` to `true` by default.     | no
+[aws.log.stream.names][res-attr-cfg]    | Toggles the `aws.log.stream.names` resource attribute. <br> Sets `enabled` to `true` by default.    | no
+[cloud.account.id][res-attr-cfg]        | Toggles the `cloud.account.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.availability_zone][res-attr-cfg] | Toggles the `cloud.availability_zone` resource attribute. <br> Sets `enabled` to `true` by default. | no
+[cloud.platform][res-attr-cfg]          | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.          | no
+[cloud.provider][res-attr-cfg]          | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.          | no
+[cloud.region][res-attr-cfg]            | Toggles the `cloud.region` resource attribute. <br> Sets `enabled` to `true` by default.            | no
+
+### eks
+
+The `eks` block adds resource attributes for Amazon EKS.
+
+The `eks` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#eks--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### eks > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                           | Description                                                                                 | Required
+------------------------------- | ------------------------------------------------------------------------------------------- | --------
+[cloud.platform][res-attr-cfg]  | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.  | no
+[cloud.provider][res-attr-cfg]  | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.  | no
+
+Example values:
+* `cloud.provider`: `"aws"`
+* `cloud.platform`: `"aws_eks"`
+
+### elasticbeanstalk
+
+The `elasticbeanstalk` block reads the AWS X-Ray configuration file available on all Beanstalk instances with [X-Ray Enabled][].
+
+[X-Ray Enabled]: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environment-configuration-debugging.html
+
+The `elasticbeanstalk` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#elasticbeanstalk--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### elasticbeanstalk > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                             | Description                                                                                   | Required
+--------------------------------- | --------------------------------------------------------------------------------------------- | --------
+[cloud.platform][res-attr-cfg]    | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.    | no
+[cloud.provider][res-attr-cfg]    | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.    | no
+[deployment.envir][res-attr-cfg]  | Toggles the `deployment.envir` resource attribute. <br> Sets `enabled` to `true` by default.  | no
+[service.instance][res-attr-cfg]  | Toggles the `service.instance` resource attribute. <br> Sets `enabled` to `true` by default.  | no
+[service.version][res-attr-cfg]   | Toggles the `service.version` resource attribute. <br> Sets `enabled` to `true` by default.   | no
+
+Example values:
+* `cloud.provider`: `"aws"`
+* `cloud.platform`: `"aws_elastic_beanstalk"`
+
+### lambda
+
+The `lambda` block uses the AWS Lambda [runtime environment variables][lambda-env-vars] to retrieve various resource attributes.
+
+[lambda-env-vars]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime
+
+The `lambda` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#lambda--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### lambda > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                 | Description                                                                                         | Required
+------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[aws.log.group.names][res-attr-cfg]   | Toggles the `aws.log.group.names` resource attribute. <br> Sets `enabled` to `true` by default.     | no
+[aws.log.stream.names][res-attr-cfg]  | Toggles the `aws.log.stream.names` resource attribute. <br> Sets `enabled` to `true` by default.    | no
+[cloud.platform][res-attr-cfg]        | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.          | no
+[cloud.provider][res-attr-cfg]        | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.          | no
+[cloud.region][res-attr-cfg]          | Toggles the `cloud.region` resource attribute. <br> Sets `enabled` to `true` by default.            | no
+[faas.instance][res-attr-cfg]         | Toggles the `faas.instance` resource attribute. <br> Sets `enabled` to `true` by default.           | no
+[faas.max_memory][res-attr-cfg]       | Toggles the `faas.max_memory` resource attribute. <br> Sets `enabled` to `true` by default.         | no
+[faas.name][res-attr-cfg]             | Toggles the `faas.name` resource attribute. <br> Sets `enabled` to `true` by default.               | no
+[faas.version][res-attr-cfg]          | Toggles the `faas.version` resource attribute. <br> Sets `enabled` to `true` by default.            | no
+
+[Cloud semantic conventions][]:
+* `cloud.provider`: `"aws"`
+* `cloud.platform`: `"aws_lambda"`
+* `cloud.region`: `$AWS_REGION`
+
+[Function as a Service semantic conventions][] and [AWS Lambda semantic conventions][]:
+* `faas.name`: `$AWS_LAMBDA_FUNCTION_NAME`
+* `faas.version`: `$AWS_LAMBDA_FUNCTION_VERSION`
+* `faas.instance`: `$AWS_LAMBDA_LOG_STREAM_NAME`
+* `faas.max_memory`: `$AWS_LAMBDA_FUNCTION_MEMORY_SIZE`
+
+[AWS Logs semantic conventions][]:
+* `aws.log.group.names`: `$AWS_LAMBDA_LOG_GROUP_NAME`
+* `aws.log.stream.names`: `$AWS_LAMBDA_LOG_STREAM_NAME`
+
+[Cloud semantic conventions]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/cloud.md
+[Function as a Service semantic conventions]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/faas.md
+[AWS Lambda semantic conventions]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#resource-detector
+[AWS Logs semantic conventions]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/cloud_provider/aws/logs.md
+
+### azure
+
+The `azure` block queries the [Azure Instance Metadata Service][] to retrieve various resource attributes.
+
+[Azure Instance Metadata Service]: https://aka.ms/azureimds
+
+The `azure` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#azure--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### azure > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                    | Description                                                                                         | Required
+---------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[azure.resourcegroup.name][res-attr-cfg] | Toggles the `azure.resourcegroup.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[azure.vm.name][res-attr-cfg]            | Toggles the `azure.vm.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[azure.vm.scaleset.name][res-attr-cfg]   | Toggles the `azure.vm.scaleset.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[azure.vm.size][res-attr-cfg]            | Toggles the `azure.vm.size` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.account.id][res-attr-cfg]         | Toggles the `cloud.account.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.platform][res-attr-cfg]           | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.provider][res-attr-cfg]           | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.region][res-attr-cfg]             | Toggles the `cloud.region` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[host.id][res-attr-cfg]                  | Toggles the `host.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[host.name][res-attr-cfg]                | Toggles the `host.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+
+Example values:
+* `cloud.provider`: `"azure"`
+* `cloud.platform`: `"azure_vm"`
+
+### aks
+
+The `aks` block adds resource attributes related to Azure AKS.
+
+The `aks` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#aks--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### aks > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                           | Description                                                                                 | Required
+------------------------------- | ------------------------------------------------------------------------------------------- | --------
+[cloud.platform][res-attr-cfg]  | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.  | no
+[cloud.provider][res-attr-cfg]  | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.  | no
+
+Example values:
+* `cloud.provider`: `"azure"`
+* `cloud.platform`: `"azure_vm"`
+
+### consul
+
+The `consul` block queries a Consul agent and reads its configuration endpoint to retrieve values for resource attributes.
+
+The `consul` block supports the following attributes:
+
+Attribute    | Type           | Description                                                                 | Default     | Required
+------------ |--------------- | --------------------------------------------------------------------------- |-------------| --------
+`address`    | `string`       | The address of the Consul server | `""`        | no
+`datacenter` | `string`       | Datacenter to use. If not provided, the default agent datacenter is used. | `""`        | no
+`token`      | `secret`       | A per-request ACL token which overrides the Consul agent's default (empty) token. | `""`        | no
+`namespace`  | `string`       | The name of the namespace to send along for the request. | `""`        | no
+`meta`       | `list(string)` | Allowlist of [Consul Metadata][] keys to use as resource attributes. | `[]`        | no
+
+`token` is only required if [Consul's ACL System][] is enabled.
+
+[Consul Metadata]: https://www.consul.io/docs/agent/options#node_meta
+[Consul's ACL System]: https://www.consul.io/docs/security/acl/acl-system
+
+The `consul` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#consul--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### consul > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                   | Description                                                                                         | Required
+--------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[cloud.region][res-attr-cfg]        | Toggles the `cloud.region` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[host.id][res-attr-cfg]        | Toggles the `host.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[host.name][res-attr-cfg]        | Toggles the `host.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+
+### docker
+
+The `docker` block queries the Docker daemon to retrieve various resource attributes from the host machine.
+
+You need to mount the Docker socket (`/var/run/docker.sock` on Linux) to contact the Docker daemon.
+Docker detection does not work on MacOS.
+
+The `docker` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#docker--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### docker > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                   | Description                                                                                         | Required
+--------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[host.name][res-attr-cfg]        | Toggles the `host.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[os.type][res-attr-cfg]        | Toggles the `os.type` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+
+### gcp
+
+The `gcp` block detects resource attributes using the [Google Cloud Client Libraries for Go][], which reads resource information from the [GCP metadata server][].
+The detector also uses environment variables to identify which GCP platform the application is running on, and assigns appropriate resource attributes for that platform. 
+
+Use the `gcp` detector regardless of the GCP platform {{< param "PRODUCT_ROOT_NAME" >}} is running on.
+
+[Google Cloud Client Libraries for Go]: https://github.com/googleapis/google-cloud-go
+[GCP metadata server]: https://cloud.google.com/compute/docs/storing-retrieving-metadata
+
+The `gcp` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#gcp--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### gcp > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                   | Description                                                                                         | Required
+--------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[cloud.account.id][res-attr-cfg]        | Toggles the `cloud.account.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.availability_zone][res-attr-cfg]        | Toggles the `cloud.availability_zone` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.platform][res-attr-cfg]        | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.provider][res-attr-cfg]        | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[cloud.region][res-attr-cfg]        | Toggles the `cloud.region` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[faas.id][res-attr-cfg]        | Toggles the `faas.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[faas.instance][res-attr-cfg]        | Toggles the `faas.instance` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[faas.name][res-attr-cfg]        | Toggles the `faas.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[faas.version][res-attr-cfg]        | Toggles the `faas.version` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[gcp.cloud_run.job.execution][res-attr-cfg]        | Toggles the `gcp.cloud_run.job.execution` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[gcp.cloud_run.job.task_index][res-attr-cfg]        | Toggles the `gcp.cloud_run.job.task_index` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[gcp.gce.instance.hostname][res-attr-cfg]        | Toggles the `gcp.gce.instance.hostname` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[gcp.gce.instance.name][res-attr-cfg]        | Toggles the `gcp.gce.instance.name` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.id][res-attr-cfg]        | Toggles the `host.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[host.name][res-attr-cfg]        | Toggles the `host.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[host.type][res-attr-cfg]        | Toggles the `host.type` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[k8s.cluster.name][res-attr-cfg]        | Toggles the `k8s.cluster.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+
+#### Google Compute Engine (GCE) metadata
+
+* `cloud.provider`: `"gcp"`
+* `cloud.platform`: `"gcp_compute_engine"`
+* `cloud.account.id`: project id
+* `cloud.region`: e.g. `"us-central1"`
+* `cloud.availability_zone`: e.g. `"us-central1-c"`
+* `host.id`: instance id
+* `host.name`: instance name
+* `host.type`: machine type
+* (optional) `gcp.gce.instance.hostname`
+* (optional) `gcp.gce.instance.name`
+
+#### Google Kubernetes Engine (GKE) metadata
+
+* `cloud.provider`: `"gcp"`
+* `cloud.platform`: `"gcp_kubernetes_engine"`
+* `cloud.account.id`: project id
+* `cloud.region`: only for regional GKE clusters; e.g. `"us-central1"`
+* `cloud.availability_zone`: only for zonal GKE clusters; e.g. `"us-central1-c"`
+* `k8s.cluster.name`
+* `host.id`: instance id
+* `host.name`: instance name; only when workload identity is disabled
+
+One known issue happens when GKE workload identity is enabled. The GCE metadata endpoints won't be available, 
+and the GKE resource detector won't be able to determine `host.name`. 
+If this happens, you can set `host.name` from one of the following resources:
+- Get the `node.name` through the [downward API][] with the `env` detector.
+- Get the Kubernetes node name from the Kubernetes API (with `k8s.io/client-go`).
+
+[downward API]: https://kubernetes.io/docs/concepts/workloads/pods/downward-api/
+
+#### Google Cloud Run Services metadata
+
+* `cloud.provider`: `"gcp"`
+* `cloud.platform`: `"gcp_cloud_run"`
+* `cloud.account.id`: project id
+* `cloud.region`: e.g. `"us-central1"`
+* `faas.id`: instance id
+* `faas.name`: service name
+* `faas.version`: service revision
+
+#### Cloud Run Jobs metadata
+
+* `cloud.provider`: `"gcp"`
+* `cloud.platform`: `"gcp_cloud_run"`
+* `cloud.account.id`: project id
+* `cloud.region`: e.g. `"us-central1"`
+* `faas.id`: instance id
+* `faas.name`: service name
+* `gcp.cloud_run.job.execution`: e.g. `"my-service-ajg89"`
+* `gcp.cloud_run.job.task_index`: e.g. `"0"`
+
+#### Google Cloud Functions metadata
+
+* `cloud.provider`: `"gcp"`
+* `cloud.platform`: `"gcp_cloud_functions"`
+* `cloud.account.id`: project id
+* `cloud.region`: e.g. `"us-central1"`
+* `faas.id`: instance id
+* `faas.name`: function name
+* `faas.version`: function version
+
+#### Google App Engine metadata
+
+* `cloud.provider`: `"gcp"`
+* `cloud.platform`: `"gcp_app_engine"`
+* `cloud.account.id`: project id
+* `cloud.region`: e.g. `"us-central1"`
+* `cloud.availability_zone`: e.g. `"us-central1-c"`
+* `faas.id`: instance id
+* `faas.name`: service name
+* `faas.version`: service version
+
+### heroku
+
+The `heroku` block adds resource attributes derived from [Heroku dyno metadata][].
+
+The `heroku` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#heroku--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### heroku > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                   | Description                                                                                         | Required
+--------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[cloud.provider][res-attr-cfg]        | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[heroku.app.id][res-attr-cfg]        | Toggles the `heroku.app.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[heroku.dyno.id][res-attr-cfg]        | Toggles the `heroku.dyno.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[heroku.release.commit][res-attr-cfg]        | Toggles the `heroku.release.commit` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[heroku.release.creation_timestamp][res-attr-cfg]        | Toggles the `heroku.release.creation_timestamp` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[service.instance.id][res-attr-cfg]        | Toggles the `service.instance.id` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[service.name][res-attr-cfg]        | Toggles the `service.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[service.version][res-attr-cfg]        | Toggles the `service.version` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+
+When [Heroku dyno metadata][] is active, Heroku applications publish information through environment variables.
+We map these environment variables to resource attributes as follows:
+
+| Dyno metadata environment variable | Resource attribute                  |
+|------------------------------------|-------------------------------------|
+| `HEROKU_APP_ID`                    | `heroku.app.id`                     |
+| `HEROKU_APP_NAME`                  | `service.name`                      |
+| `HEROKU_DYNO_ID`                   | `service.instance.id`               |
+| `HEROKU_RELEASE_CREATED_AT`        | `heroku.release.creation_timestamp` |
+| `HEROKU_RELEASE_VERSION`           | `service.version`                   |
+| `HEROKU_SLUG_COMMIT`               | `heroku.release.commit`             |
+
+For more information, see the [Heroku cloud provider documentation][] under the [OpenTelemetry specification semantic conventions][].
+
+[Heroku dyno metadata]: https://devcenter.heroku.com/articles/dyno-metadata
+[Heroku cloud provider documentation]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/cloud_provider/heroku.md
+[OpenTelemetry specification semantic conventions]: https://github.com/open-telemetry/opentelemetry-specification
+
+### system
+
+The `system` block queries the host machine to retrieve various resource attributes.
+
+{{% admonition type="note" %}}
+
+Use the [Docker](#docker) detector if running {{< param "PRODUCT_ROOT_NAME" >}} as a Docker container.
+
+{{% /admonition %}}
+
+The `system` block supports the following attributes:
+
+Attribute          | Type            | Description                                                                 | Default         | Required
+------------------ | --------------- | --------------------------------------------------------------------------- |---------------- | --------
+`hostname_sources` | `list(string)`  | A priority list of sources from which the hostname will be fetched.         | `["dns", "os"]` | no
+
+The valid options for `hostname_sources` are:
+* `"dns"`: Uses multiple sources to get the fully qualified domain name. 
+Firstly, it looks up the host name in the local machine's `hosts` file. If that fails, it looks up the CNAME. 
+Lastly, if that fails, it does a reverse DNS query. Note: this hostname source may produce unreliable results on Windows. 
+To produce a FQDN, Windows hosts might have better results using the "lookup" hostname source, which is mentioned below.
+* `"os"`: Provides the hostname provided by the local machine's kernel.
+* `"cname"`: Provides the canonical name, as provided by `net.LookupCNAME` in the Go standard library. 
+Note: this hostname source may produce unreliable results on Windows.
+* `"lookup"`: Does a reverse DNS lookup of the current host's IP address.
+
+In case of an error in fetching a hostname from a source, the next source from the list of `hostname_sources` will be considered.
+
+The `system` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#system--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### system > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                                   | Description                                                                                         | Required
+--------------------------------------- | --------------------------------------------------------------------------------------------------- | --------
+[host.arch][res-attr-cfg]        | Toggles the `host.arch` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.cpu.cache.l2.size][res-attr-cfg]        | Toggles the `host.cpu.cache.l2.size` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.cpu.family][res-attr-cfg]        | Toggles the `host.cpu.family` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.cpu.model.id][res-attr-cfg]        | Toggles the `host.cpu.model.id` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.cpu.model.name][res-attr-cfg]        | Toggles the `host.cpu.model.name` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.cpu.stepping][res-attr-cfg]        | Toggles the `host.cpu.stepping` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.cpu.vendor.id][res-attr-cfg]        | Toggles the `host.cpu.vendor.id` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.id][res-attr-cfg]        | Toggles the `host.id` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[host.name][res-attr-cfg]        | Toggles the `host.name` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+[os.description][res-attr-cfg]        | Toggles the `os.description` resource attribute. <br> Sets `enabled` to `false` by default.        | no
+[os.type][res-attr-cfg]        | Toggles the `os.type` resource attribute. <br> Sets `enabled` to `true` by default.        | no
+
+### openshift
+
+The `openshift` block queries the OpenShift and Kubernetes APIs to retrieve various resource attributes.
+
+The `openshift` block supports the following attributes:
+
+Attribute  | Type      | Description                                             | Default     | Required
+---------- |---------- | ------------------------------------------------------- |-------------| --------
+`address`  | `string`  | Address of the OpenShift API server.                    | _See below_ | no
+`token`    | `string`  | Token used to identify against the OpenShift API server.| ""          | no
+
+The "get", "watch", and "list" permissions are required:
+
+```yaml
+kind: ClusterRole
+metadata:
+  name: grafana-agent
+rules:
+- apiGroups: ["config.openshift.io"]
+  resources: ["infrastructures", "infrastructures/status"]
+  verbs: ["get", "watch", "list"]
+```
+
+By default, the API address is determined from the environment variables `KUBERNETES_SERVICE_HOST`, 
+`KUBERNETES_SERVICE_PORT` and the service token is read from `/var/run/secrets/kubernetes.io/serviceaccount/token`. 
+If TLS is not explicitly disabled and no `ca_file` is configured, `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt` is used. 
+The determination of the API address, `ca_file`, and the service token is skipped if they are set in the configuration.
+
+The `openshift` block supports the following blocks:
+
+Block                                          | Description                                          | Required
+---------------------------------------------- | ---------------------------------------------------- | --------
+[resource_attributes](#openshift--resource_attributes) | Configures which resource attributes to add. | no
+[tls](#openshift--tls) | TLS settings for the connection with the OpenShift API. | yes
+
+#### openshift > tls
+
+The `tls` block configures TLS settings used for the connection to the gRPC
+server.
+
+{{< docs/shared lookup="flow/reference/components/otelcol-tls-config-block.md" source="agent" version="<AGENT_VERSION>" >}}
+
+#### openshift > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                             | Description                                                                                   | Required
+--------------------------------- | --------------------------------------------------------------------------------------------- | --------
+[cloud.platform][res-attr-cfg]    | Toggles the `cloud.platform` resource attribute. <br> Sets `enabled` to `true` by default.    | no
+[cloud.provider][res-attr-cfg]    | Toggles the `cloud.provider` resource attribute. <br> Sets `enabled` to `true` by default.    | no
+[cloud.region][res-attr-cfg]      | Toggles the `cloud.region` resource attribute. <br> Sets `enabled` to `true` by default.      | no
+[k8s.cluster.name][res-attr-cfg]  | Toggles the `k8s.cluster.name` resource attribute. <br> Sets `enabled` to `true` by default.  | no
+
+### kubernetes_node
+
+The `kubernetes_node` block queries the Kubernetes API server to retrieve various node resource attributes.
+
+The `kubernetes_node` block supports the following attributes:
+
+Attribute           | Type     | Description                                                               | Default           | Required
+------------------- |--------- | ------------------------------------------------------------------------- |------------------ | --------
+`auth_type`         | `string` | Configures how to authenticate to the K8s API server.                     | `"none"`          | no
+`context`           | `string` | Override the current context when `auth_type` is set to `"kubeConfig"`.   | `""`              | no
+`node_from_env_var` | `string` | The name of an environment variable from which to retrieve the node name. | `"K8S_NODE_NAME"` | no
+
+The "get" and "list" permissions are required:
+
+```yaml
+kind: ClusterRole
+metadata:
+  name: grafana-agent
+rules:
+  - apiGroups: [""]
+    resources: ["nodes"]
+    verbs: ["get", "list"]
+```
+
+`auth_type` can be set to one of the following:
+* `none`: no authentication.
+* `serviceAccount`: use the standard service account token provided to the agent pod.
+* `kubeConfig`: use credentials from `~/.kube/config`.
+
+The `kubernetes_node` block supports the following blocks:
+
+Block                                          | Description                                       | Required
+---------------------------------------------- | ------------------------------------------------- | --------
+[resource_attributes](#kubernetes_node--resource_attributes) | Configures which resource attributes to add.      | no
+
+#### kubernetes_node > resource_attributes
+
+The `resource_attributes` block supports the following blocks:
+
+Block                          | Description                                                                                | Required
+------------------------------ | ------------------------------------------------------------------------------------------ | --------
+[k8s.node.name][res-attr-cfg]  | Toggles the `k8s.node.name` resource attribute. <br> Sets `enabled` to `true` by default.  | no
+[k8s.node.uid][res-attr-cfg]   | Toggles the `k8s.node.uid` resource attribute. <br> Sets `enabled` to `true` by default.   | no
+
+## Common configuration
+
+### Resource attribute config
+
+This block describes how to configure resource attributes such as `k8s.node.name` and `azure.vm.name`.
+Every block is configured using the same set of attributes. 
+Only the default values for those attributes might differ across resource attributes.
+For example, some resource attributes have `enabled` set to `true` by default, whereas others do not. 
+
+The following attributes are supported:
+
+Attribute |  Type   | Description                                                                         | Default      | Required
+--------- | ------- | ----------------------------------------------------------------------------------- |------------- | --------
+`enabled` | `bool`  | Toggles whether to add the resource attribute to the span, log, or metric resource. | _See below_  | no
+
+To see the default value for `enabled`, refer to the tables in the sections above which list the resource attributes blocks.
+The "Description" column will state either...
+
+> Sets `enabled` to `true` by default.
+
+... or:
+
+> Sets `enabled` to `false` by default.
+
+## Exported fields
+
+The following fields are exported and can be referenced by other components:
+
+Name | Type | Description
+---- | ---- | -----------
+`input` | `otelcol.Consumer` | A value that other components can use to send telemetry data to.
+
+`input` accepts `otelcol.Consumer` OTLP-formatted data for any telemetry signal of these types:
+* logs
+* metrics
+* traces
+
+## Component health
+
+`otelcol.processor.resourcedetection` is only reported as unhealthy if given an invalid
+configuration.
+
+## Debug information
+
+`otelcol.processor.resourcedetection` does not expose any component-specific debug
+information.
+
+## Examples
+
+### env detector
+
+If you set up a `OTEL_RESOURCE_ATTRIBUTES` environment variable with value of `TestKey=TestValue`,
+then all logs, metrics, and traces will have a resource attribute with a key `TestKey` and value of `TestValue`.
+
+```river
+otelcol.processor.resourcedetection "default" {
+  detectors = ["env"]
+
+  output {
+    logs    = [otelcol.exporter.otlp.default.input]
+    metrics = [otelcol.exporter.otlp.default.input]
+    traces  = [otelcol.exporter.otlp.default.input]
+  }
+}
+```
+
+### env and ec2
+
+There is no need to put in an `ec2 {}` River block.
+The `ec2` defaults will be applied automatically, as specified in [ec2][].
+
+```river
+otelcol.processor.resourcedetection "default" {
+  detectors = ["env", "ec2"]
+
+  output {
+    logs    = [otelcol.exporter.otlp.default.input]
+    metrics = [otelcol.exporter.otlp.default.input]
+    traces  = [otelcol.exporter.otlp.default.input]
+  }
+}
+```
+
+### ec2 with default resource attributes
+
+There is no need to put in a `ec2 {}` River block.
+The `ec2` defaults will be applied automatically, as specified in [ec2][].
+
+```river
+otelcol.processor.resourcedetection "default" {
+  detectors = ["ec2"]
+
+  output {
+    logs    = [otelcol.exporter.otlp.default.input]
+    metrics = [otelcol.exporter.otlp.default.input]
+    traces  = [otelcol.exporter.otlp.default.input]
+  }
+}
+```
+
+### ec2 with explicit resource attributes
+
+```river
+otelcol.processor.resourcedetection "default" {
+  detectors = ["ec2"]
+  ec2 {
+    tags = ["^tag1$", "^tag2$", "^label.*$"]
+    resource_attributes {
+      cloud.account.id  { enabled = true }
+      cloud.availability_zone  { enabled = true }
+      cloud.platform  { enabled = true }
+      cloud.provider  { enabled = true }
+      cloud.region  { enabled = true }
+      host.id  { enabled = true }
+      host.image.id  { enabled = false }
+      host.name  { enabled = false }
+      host.type  { enabled = false }
+    }
+  }
+
+  output {
+    logs    = [otelcol.exporter.otlp.default.input]
+    metrics = [otelcol.exporter.otlp.default.input]
+    traces  = [otelcol.exporter.otlp.default.input]
+  }
+}
+```
+
+### kubernetes_node
+
+This example uses the default `node_from_env_var` option of `K8S_NODE_NAME`.
+
+There is no need to put in a `kubernetes_node {}` River block.
+The `kubernetes_node` defaults will be applied automatically, as specified in [kubernetes_node][].
+
+```river
+otelcol.processor.resourcedetection "default" {
+  detectors = ["kubernetes_node"]
+
+  output {
+    logs    = [otelcol.exporter.otlp.default.input]
+    metrics = [otelcol.exporter.otlp.default.input]
+    traces  = [otelcol.exporter.otlp.default.input]
+  }
+}
+```
+
+You need to add this to your workload:
+
+```yaml
+        env:
+          - name: K8S_NODE_NAME
+            valueFrom:
+              fieldRef:
+                fieldPath: spec.nodeName
+```
+
+### kubernetes_node with a custom environment variable
+
+This example uses a custom `node_from_env_var` set to `my_custom_var`.
+
+```river
+otelcol.processor.resourcedetection "default" {
+  detectors = ["kubernetes_node"]
+  kubernetes_node {
+    node_from_env_var = "my_custom_var"
+  }
+
+  output {
+    logs    = [otelcol.exporter.otlp.default.input]
+    metrics = [otelcol.exporter.otlp.default.input]
+    traces  = [otelcol.exporter.otlp.default.input]
+  }
+}
+```
+
+You need to add this to your workload:
+
+```yaml
+        env:
+          - name: my_custom_var
+            valueFrom:
+              fieldRef:
+                fieldPath: spec.nodeName
+```
+<!-- START GENERATED COMPATIBLE COMPONENTS -->
+
+## Compatible components
+
+`otelcol.processor.resourcedetection` can accept arguments from the following components:
+
+- Components that export [OpenTelemetry `otelcol.Consumer`]({{< relref "../compatibility/#opentelemetry-otelcolconsumer-exporters" >}})
+
+`otelcol.processor.resourcedetection` has exports that can be consumed by the following components:
+
+- Components that consume [OpenTelemetry `otelcol.Consumer`]({{< relref "../compatibility/#opentelemetry-otelcolconsumer-consumers" >}})
+
+{{% admonition type="note" %}}
+
+Connecting some components may not be sensible or components may require further configuration to make the 
+connection work correctly. Refer to the linked documentation for more details.
+
+{{% /admonition %}}
+
+<!-- END GENERATED COMPATIBLE COMPONENTS -->
\ No newline at end of file
diff --git a/go.mod b/go.mod
index b8546af688cf..d63dada2594a 100644
--- a/go.mod
+++ b/go.mod
@@ -116,6 +116,7 @@ require (
 	github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.87.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor v0.87.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.87.0
+	github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.87.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/processor/servicegraphprocessor v0.87.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/processor/spanmetricsprocessor v0.87.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/processor/spanprocessor v0.87.0
@@ -621,7 +622,9 @@ require (
 	dario.cat/mergo v1.0.0 // indirect
 	github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1 // indirect
 	github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1 // indirect
+	github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.20.0 // indirect
 	github.com/Shopify/sarama v1.38.1 // indirect
+	github.com/Showmax/go-fqdn v1.0.0 // indirect
 	github.com/Workiva/go-datastructures v1.1.0 // indirect
 	github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0 // indirect
 	github.com/channelmeter/iso8601duration v0.0.0-20150204201828-8da3af7a2a61 // indirect
@@ -640,8 +643,11 @@ require (
 	github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect
 	github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect
 	github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
+	github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.87.0 // indirect
+	github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.87.0 // indirect
 	github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig v0.87.0 // indirect
 	github.com/open-telemetry/opentelemetry-collector-contrib/internal/kafka v0.87.0 // indirect
+	github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.87.0 // indirect
 	github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheusremotewrite v0.87.0 // indirect
 	github.com/openshift/api v3.9.0+incompatible // indirect
 	github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142 // indirect
diff --git a/go.sum b/go.sum
index 8a4a155e271f..9fbcbc7e28df 100644
--- a/go.sum
+++ b/go.sum
@@ -183,6 +183,8 @@ github.com/DataDog/datadog-go v0.0.0-20160329135253-cc2f4770f4d6/go.mod h1:LButx
 github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
 github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw=
 github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962/go.mod h1:kC29dT1vFpj7py2OvG1khBdQpo3kInWP+6QipLbdngo=
+github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.20.0 h1:tk85AYGwOf6VNtoOQi8w/kVDi2vmPxp3/OU2FsUpdcA=
+github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.20.0/go.mod h1:Xx0VKh7GJ4si3rmElbh19Mejxz68ibWg/J30ZOMrqzU=
 github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
 github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
 github.com/IBM/sarama v1.42.1 h1:wugyWa15TDEHh2kvq2gAy1IHLjEjuYOYgXz/ruC/OSQ=
@@ -237,6 +239,8 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWso
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc=
 github.com/Shopify/toxiproxy/v2 v2.5.0/go.mod h1:yhM2epWtAmel9CB8r2+L+PCmhH6yH2pITaPAo7jxJl0=
+github.com/Showmax/go-fqdn v1.0.0 h1:0rG5IbmVliNT5O19Mfuvna9LL7zlHyRfsSvBPZmF9tM=
+github.com/Showmax/go-fqdn v1.0.0/go.mod h1:SfrFBzmDCtCGrnHhoDjuvFnKsWjEQX/Q9ARZvOrJAko=
 github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
 github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
@@ -1743,6 +1747,8 @@ github.com/open-telemetry/opentelemetry-collector-contrib/extension/oauth2client
 github.com/open-telemetry/opentelemetry-collector-contrib/extension/oauth2clientauthextension v0.87.0/go.mod h1:DRpgdIDMa+CFE96SoEPwigGBuZbwSNWotTgkJlrZMVc=
 github.com/open-telemetry/opentelemetry-collector-contrib/extension/sigv4authextension v0.87.0 h1:Z4o71/rS7mmpJ/9uzta3/nTaT+vKt0CU35o4inDLA9Y=
 github.com/open-telemetry/opentelemetry-collector-contrib/extension/sigv4authextension v0.87.0/go.mod h1:clScLUe8m0CTZMcV0scqq+fFFvw5Q1dASkYlYsrRptM=
+github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.87.0 h1:JJsQ6iMFIDb7W6uLh6LQ5k4XOgWolr7ugVBoeV4l7hQ=
+github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.87.0/go.mod h1:rDdtaUrMV6TJHqssyiYSfsLfFN1pIg4JOTDaE9AUapQ=
 github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.87.0 h1:W4Ty2pSyge/qNAOILO6HqyKrAcgALs0bn5CmpGZJXVo=
 github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.87.0/go.mod h1:3EFmVoLcdM8Adj75N8TGJ4txDB29oW1chTLCFiL/wxs=
 github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.87.0 h1:ekT4/I9J484j4yR/0VHj5AGtgv8KmNd+e4oXxNJNR/o=
@@ -1755,6 +1761,8 @@ github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8stest v0.87
 github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8stest v0.87.0/go.mod h1:ntSfqIeoGj0O+pXXyqDG9iTAw/PQg2JsO26EJ1GAKto=
 github.com/open-telemetry/opentelemetry-collector-contrib/internal/kafka v0.87.0 h1:kDamu7uZHRmeJWqaJg42LSgprRGokmQ4t8ACslzS0GU=
 github.com/open-telemetry/opentelemetry-collector-contrib/internal/kafka v0.87.0/go.mod h1:EAw9aBkrDIDWQvRBdJiDkaJmCqcgZpiZzYZEvOjg4uI=
+github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.87.0 h1:8pVElJ4AMIiJxS+sxnK9CX73RED7iv/FYbqkvvX01ig=
+github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.87.0/go.mod h1:zRQU4eN6rNXeVKD8g2p2Czb88o/Hd2BkVdar5nCk0+k=
 github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.87.0 h1:sx1ye7Y2rJ2qi11i2ih9T7BocxaV0uaBBf7B8ijCYpU=
 github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.87.0/go.mod h1:AobBiNPFNHUm0MJFTieajasG/xNMjMYI7BGGTSKh0xg=
 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchpersignal v0.87.0 h1:sy75u6ZwBvRwv9RjEF65SqlkBsAeZFqF4+eFOLhIsJQ=
@@ -1787,6 +1795,8 @@ github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattribute
 github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor v0.87.0/go.mod h1:g6H0fB9TW03Lb8M+H0BXtgQp7gPncIwf3Fk73xOs9EA=
 github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.87.0 h1:QJKdtNcsxBhG2ZwSzYRVI0oxUqBJJvhfWf0OnjHU3jY=
 github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.87.0/go.mod h1:skMmFcl+gxyiOQXvwHc0IKpC73iyQ7zl9r1aRNmPMwI=
+github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.87.0 h1:gEv7UNu4K5ptvKIpWQmVS+0XMrIzqZWczcjyhLnsx9M=
+github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.87.0/go.mod h1:6Rnjwj4bZU7Ab+nLD1YqQlbdsnsKoOR/OzyI42+PyE8=
 github.com/open-telemetry/opentelemetry-collector-contrib/processor/servicegraphprocessor v0.87.0 h1:BIGb6dfmaTlDE7KbiQUhnD9SvL5HanbJbWJrnzURfPY=
 github.com/open-telemetry/opentelemetry-collector-contrib/processor/servicegraphprocessor v0.87.0/go.mod h1:EnaQxXfCCWkSEfsQbGOvYbeJ/EuqvtMYTLTq8RN6TiY=
 github.com/open-telemetry/opentelemetry-collector-contrib/processor/spanmetricsprocessor v0.87.0 h1:4l/QetnprIMethZYfD2RK+MfMR83f6QycYb9bhJFItc=