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 }