github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/internal/adapters/terraform/aws/rds/adapt.go (about)

     1  package rds
     2  
     3  import (
     4  	"github.com/khulnasoft-lab/defsec/pkg/providers/aws/rds"
     5  	"github.com/khulnasoft-lab/defsec/pkg/terraform"
     6  	defsecTypes "github.com/khulnasoft-lab/defsec/pkg/types"
     7  )
     8  
     9  func Adapt(modules terraform.Modules) rds.RDS {
    10  	return rds.RDS{
    11  		Instances:       getInstances(modules),
    12  		Clusters:        getClusters(modules),
    13  		Classic:         getClassic(modules),
    14  		Snapshots:       getSnapshots(modules),
    15  		ParameterGroups: getParameterGroups(modules),
    16  	}
    17  }
    18  
    19  func getInstances(modules terraform.Modules) (instances []rds.Instance) {
    20  	for _, resource := range modules.GetResourcesByType("aws_db_instance") {
    21  		instances = append(instances, adaptInstance(resource, modules))
    22  	}
    23  
    24  	return instances
    25  }
    26  
    27  func getParameterGroups(modules terraform.Modules) (parametergroups []rds.ParameterGroups) {
    28  	for _, resource := range modules.GetResourcesByType("aws_db_parameter_group") {
    29  		parametergroups = append(parametergroups, adaptDBParameterGroups(resource, modules))
    30  	}
    31  
    32  	return parametergroups
    33  }
    34  
    35  func getSnapshots(modules terraform.Modules) (snapshots []rds.Snapshots) {
    36  	for _, resource := range modules.GetResourcesByType("aws_db_snapshot") {
    37  		snapshots = append(snapshots, adaptDBSnapshots(resource, modules))
    38  	}
    39  
    40  	return snapshots
    41  }
    42  
    43  func getClusters(modules terraform.Modules) (clusters []rds.Cluster) {
    44  
    45  	rdsInstanceMaps := modules.GetChildResourceIDMapByType("aws_rds_cluster_instance")
    46  	for _, resource := range modules.GetResourcesByType("aws_rds_cluster") {
    47  		cluster, instanceIDs := adaptCluster(resource, modules)
    48  		for _, id := range instanceIDs {
    49  			rdsInstanceMaps.Resolve(id)
    50  		}
    51  		clusters = append(clusters, cluster)
    52  	}
    53  
    54  	orphanResources := modules.GetResourceByIDs(rdsInstanceMaps.Orphans()...)
    55  
    56  	if len(orphanResources) > 0 {
    57  		orphanage := rds.Cluster{
    58  			Metadata:                  defsecTypes.NewUnmanagedMetadata(),
    59  			BackupRetentionPeriodDays: defsecTypes.IntDefault(1, defsecTypes.NewUnmanagedMetadata()),
    60  			ReplicationSourceARN:      defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
    61  			PerformanceInsights: rds.PerformanceInsights{
    62  				Metadata: defsecTypes.NewUnmanagedMetadata(),
    63  				Enabled:  defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
    64  				KMSKeyID: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
    65  			},
    66  			Instances: nil,
    67  			Encryption: rds.Encryption{
    68  				Metadata:       defsecTypes.NewUnmanagedMetadata(),
    69  				EncryptStorage: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
    70  				KMSKeyID:       defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
    71  			},
    72  			PublicAccess:         defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
    73  			Engine:               defsecTypes.StringUnresolvable(defsecTypes.NewUnmanagedMetadata()),
    74  			LatestRestorableTime: defsecTypes.TimeUnresolvable(defsecTypes.NewUnmanagedMetadata()),
    75  		}
    76  		for _, orphan := range orphanResources {
    77  			orphanage.Instances = append(orphanage.Instances, adaptClusterInstance(orphan, modules))
    78  		}
    79  		clusters = append(clusters, orphanage)
    80  	}
    81  
    82  	return clusters
    83  }
    84  
    85  func getClassic(modules terraform.Modules) rds.Classic {
    86  	classic := rds.Classic{
    87  		DBSecurityGroups: nil,
    88  	}
    89  	for _, resource := range modules.GetResourcesByType("aws_db_security_group", "aws_redshift_security_group", "aws_elasticache_security_group") {
    90  		classic.DBSecurityGroups = append(classic.DBSecurityGroups, adaptClassicDBSecurityGroup(resource))
    91  	}
    92  	return classic
    93  }
    94  
    95  func adaptClusterInstance(resource *terraform.Block, modules terraform.Modules) rds.ClusterInstance {
    96  	clusterIdAttr := resource.GetAttribute("cluster_identifier")
    97  	clusterId := clusterIdAttr.AsStringValueOrDefault("", resource)
    98  
    99  	if clusterIdAttr.IsResourceBlockReference("aws_rds_cluster") {
   100  		if referenced, err := modules.GetReferencedBlock(clusterIdAttr, resource); err == nil {
   101  			clusterId = defsecTypes.String(referenced.FullName(), referenced.GetMetadata())
   102  		}
   103  	}
   104  
   105  	return rds.ClusterInstance{
   106  		ClusterIdentifier: clusterId,
   107  		Instance:          adaptInstance(resource, modules),
   108  	}
   109  }
   110  
   111  func adaptClassicDBSecurityGroup(resource *terraform.Block) rds.DBSecurityGroup {
   112  	return rds.DBSecurityGroup{
   113  		Metadata: resource.GetMetadata(),
   114  	}
   115  }
   116  
   117  func adaptInstance(resource *terraform.Block, modules terraform.Modules) rds.Instance {
   118  
   119  	var ReadReplicaDBInstanceIdentifiers []defsecTypes.StringValue
   120  	rrdiAttr := resource.GetAttribute("replicate_source_db")
   121  	for _, rrdi := range rrdiAttr.AsStringValues() {
   122  		ReadReplicaDBInstanceIdentifiers = append(ReadReplicaDBInstanceIdentifiers, rrdi)
   123  	}
   124  
   125  	var TagList []rds.TagList
   126  	tagres := resource.GetBlocks("tags")
   127  	for _, tagres := range tagres {
   128  
   129  		TagList = append(TagList, rds.TagList{
   130  			Metadata: tagres.GetMetadata(),
   131  		})
   132  	}
   133  
   134  	var EnabledCloudwatchLogsExports []defsecTypes.StringValue
   135  	ecweAttr := resource.GetAttribute("enabled_cloudwatch_logs_exports")
   136  	for _, ecwe := range ecweAttr.AsStringValues() {
   137  		EnabledCloudwatchLogsExports = append(EnabledCloudwatchLogsExports, ecwe)
   138  	}
   139  
   140  	replicaSource := resource.GetAttribute("replicate_source_db")
   141  	replicaSourceValue := ""
   142  	if replicaSource.IsNotNil() {
   143  		if referenced, err := modules.GetReferencedBlock(replicaSource, resource); err == nil {
   144  			replicaSourceValue = referenced.ID()
   145  		}
   146  	}
   147  	return rds.Instance{
   148  		Metadata:                         resource.GetMetadata(),
   149  		BackupRetentionPeriodDays:        resource.GetAttribute("backup_retention_period").AsIntValueOrDefault(0, resource),
   150  		ReplicationSourceARN:             defsecTypes.StringExplicit(replicaSourceValue, resource.GetMetadata()),
   151  		PerformanceInsights:              adaptPerformanceInsights(resource),
   152  		Encryption:                       adaptEncryption(resource),
   153  		PublicAccess:                     resource.GetAttribute("publicly_accessible").AsBoolValueOrDefault(false, resource),
   154  		Engine:                           resource.GetAttribute("engine").AsStringValueOrDefault(rds.EngineAurora, resource),
   155  		IAMAuthEnabled:                   resource.GetAttribute("iam_database_authentication_enabled").AsBoolValueOrDefault(false, resource),
   156  		DeletionProtection:               resource.GetAttribute("deletion_protection").AsBoolValueOrDefault(false, resource),
   157  		DBInstanceArn:                    resource.GetAttribute("arn").AsStringValueOrDefault("", resource),
   158  		StorageEncrypted:                 resource.GetAttribute("storage_encrypted").AsBoolValueOrDefault(true, resource),
   159  		DBInstanceIdentifier:             resource.GetAttribute("identifier").AsStringValueOrDefault("", resource),
   160  		EngineVersion:                    resource.GetAttribute("engine_version").AsStringValueOrDefault("", resource),
   161  		AutoMinorVersionUpgrade:          resource.GetAttribute("auto_minor_version_upgrade").AsBoolValueOrDefault(false, resource),
   162  		MultiAZ:                          resource.GetAttribute("multi_az").AsBoolValueOrDefault(false, resource),
   163  		PubliclyAccessible:               resource.GetAttribute("publicly_accessible").AsBoolValueOrDefault(false, resource),
   164  		LatestRestorableTime:             defsecTypes.TimeUnresolvable(resource.GetMetadata()),
   165  		ReadReplicaDBInstanceIdentifiers: ReadReplicaDBInstanceIdentifiers,
   166  		TagList:                          TagList,
   167  		EnabledCloudwatchLogsExports:     EnabledCloudwatchLogsExports,
   168  	}
   169  }
   170  
   171  func adaptDBParameterGroups(resource *terraform.Block, modules terraform.Modules) rds.ParameterGroups {
   172  
   173  	var Parameters []rds.Parameters
   174  	paramres := resource.GetBlocks("parameter")
   175  	for _, paramres := range paramres {
   176  
   177  		Parameters = append(Parameters, rds.Parameters{
   178  			Metadata:       paramres.GetMetadata(),
   179  			ParameterName:  defsecTypes.StringDefault("", paramres.GetMetadata()),
   180  			ParameterValue: defsecTypes.StringDefault("", paramres.GetMetadata()),
   181  		})
   182  	}
   183  
   184  	return rds.ParameterGroups{
   185  		Metadata:               resource.GetMetadata(),
   186  		DBParameterGroupName:   resource.GetAttribute("name").AsStringValueOrDefault("", resource),
   187  		DBParameterGroupFamily: resource.GetAttribute("family").AsStringValueOrDefault("", resource),
   188  		Parameters:             Parameters,
   189  	}
   190  }
   191  
   192  func adaptDBSnapshots(resource *terraform.Block, modules terraform.Modules) rds.Snapshots {
   193  
   194  	return rds.Snapshots{
   195  		Metadata:             resource.GetMetadata(),
   196  		DBSnapshotIdentifier: resource.GetAttribute("db_snapshot_identifier").AsStringValueOrDefault("", resource),
   197  		DBSnapshotArn:        resource.GetAttribute("db_snapshot_arn").AsStringValueOrDefault("", resource),
   198  		Encrypted:            resource.GetAttribute("encrypted").AsBoolValueOrDefault(true, resource),
   199  		KmsKeyId:             resource.GetAttribute("kms_key_id").AsStringValueOrDefault("", resource),
   200  		SnapshotAttributes:   nil,
   201  	}
   202  }
   203  
   204  func adaptCluster(resource *terraform.Block, modules terraform.Modules) (rds.Cluster, []string) {
   205  
   206  	clusterInstances, ids := getClusterInstances(resource, modules)
   207  
   208  	var public bool
   209  	for _, instance := range clusterInstances {
   210  		if instance.PublicAccess.IsTrue() {
   211  			public = true
   212  			break
   213  		}
   214  	}
   215  
   216  	return rds.Cluster{
   217  		Metadata:                  resource.GetMetadata(),
   218  		BackupRetentionPeriodDays: resource.GetAttribute("backup_retention_period").AsIntValueOrDefault(1, resource),
   219  		ReplicationSourceARN:      resource.GetAttribute("replication_source_identifier").AsStringValueOrDefault("", resource),
   220  		PerformanceInsights:       adaptPerformanceInsights(resource),
   221  		Instances:                 clusterInstances,
   222  		Encryption:                adaptEncryption(resource),
   223  		PublicAccess:              defsecTypes.Bool(public, resource.GetMetadata()),
   224  		Engine:                    resource.GetAttribute("engine").AsStringValueOrDefault(rds.EngineAurora, resource),
   225  		LatestRestorableTime:      defsecTypes.TimeUnresolvable(resource.GetMetadata()),
   226  	}, ids
   227  }
   228  
   229  func getClusterInstances(resource *terraform.Block, modules terraform.Modules) (clusterInstances []rds.ClusterInstance, instanceIDs []string) {
   230  	clusterInstanceResources := modules.GetReferencingResources(resource, "aws_rds_cluster_instance", "cluster_identifier")
   231  
   232  	for _, ciResource := range clusterInstanceResources {
   233  		instanceIDs = append(instanceIDs, ciResource.ID())
   234  		clusterInstances = append(clusterInstances, adaptClusterInstance(ciResource, modules))
   235  	}
   236  	return clusterInstances, instanceIDs
   237  }
   238  
   239  func adaptPerformanceInsights(resource *terraform.Block) rds.PerformanceInsights {
   240  	return rds.PerformanceInsights{
   241  		Metadata: resource.GetMetadata(),
   242  		Enabled:  resource.GetAttribute("performance_insights_enabled").AsBoolValueOrDefault(false, resource),
   243  		KMSKeyID: resource.GetAttribute("performance_insights_kms_key_id").AsStringValueOrDefault("", resource),
   244  	}
   245  }
   246  
   247  func adaptEncryption(resource *terraform.Block) rds.Encryption {
   248  	return rds.Encryption{
   249  		Metadata:       resource.GetMetadata(),
   250  		EncryptStorage: resource.GetAttribute("storage_encrypted").AsBoolValueOrDefault(false, resource),
   251  		KMSKeyID:       resource.GetAttribute("kms_key_id").AsStringValueOrDefault("", resource),
   252  	}
   253  }