github.com/aquasecurity/trivy-iac@v0.8.1-0.20240127024015-3d8e412cf0ab/internal/adapters/cloudformation/aws/ec2/instance.go (about) 1 package ec2 2 3 import ( 4 "github.com/aquasecurity/defsec/pkg/providers/aws/ec2" 5 defsecTypes "github.com/aquasecurity/defsec/pkg/types" 6 "github.com/aquasecurity/trivy-iac/pkg/scanners/cloudformation/parser" 7 ) 8 9 func getInstances(ctx parser.FileContext) (instances []ec2.Instance) { 10 instanceResources := ctx.GetResourcesByType("AWS::EC2::Instance") 11 12 for _, r := range instanceResources { 13 instance := ec2.Instance{ 14 Metadata: r.Metadata(), 15 // metadata not supported by CloudFormation at the moment - 16 // https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/655 17 MetadataOptions: ec2.MetadataOptions{ 18 Metadata: r.Metadata(), 19 HttpTokens: defsecTypes.StringDefault("optional", r.Metadata()), 20 HttpEndpoint: defsecTypes.StringDefault("enabled", r.Metadata()), 21 }, 22 UserData: r.GetStringProperty("UserData"), 23 } 24 25 if launchTemplate, ok := findRelatedLaunchTemplate(ctx, r); ok { 26 instance = launchTemplate.Instance 27 } 28 29 if instance.RootBlockDevice == nil { 30 instance.RootBlockDevice = &ec2.BlockDevice{ 31 Metadata: r.Metadata(), 32 Encrypted: defsecTypes.BoolDefault(false, r.Metadata()), 33 } 34 } 35 36 blockDevices := getBlockDevices(r) 37 for i, device := range blockDevices { 38 copyDevice := device 39 if i == 0 { 40 instance.RootBlockDevice = copyDevice 41 continue 42 } 43 instance.EBSBlockDevices = append(instance.EBSBlockDevices, device) 44 } 45 instances = append(instances, instance) 46 } 47 48 return instances 49 } 50 51 func findRelatedLaunchTemplate(fctx parser.FileContext, r *parser.Resource) (ec2.LaunchTemplate, bool) { 52 launchTemplateRef := r.GetProperty("LaunchTemplate.LaunchTemplateName") 53 if launchTemplateRef.IsString() { 54 res := findLaunchTemplateByName(fctx, launchTemplateRef) 55 if res != nil { 56 return adaptLaunchTemplate(res), true 57 } 58 } 59 60 launchTemplateRef = r.GetProperty("LaunchTemplate.LaunchTemplateId") 61 if !launchTemplateRef.IsString() { 62 return ec2.LaunchTemplate{}, false 63 } 64 65 resource := fctx.GetResourceByLogicalID(launchTemplateRef.AsString()) 66 if resource == nil { 67 return ec2.LaunchTemplate{}, false 68 } 69 return adaptLaunchTemplate(resource), true 70 } 71 72 func findLaunchTemplateByName(fctx parser.FileContext, prop *parser.Property) *parser.Resource { 73 for _, res := range fctx.GetResourcesByType("AWS::EC2::LaunchTemplate") { 74 templateName := res.GetProperty("LaunchTemplateName") 75 if templateName.IsNotString() { 76 continue 77 } 78 79 if prop.EqualTo(templateName.AsString()) { 80 return res 81 } 82 } 83 84 return nil 85 } 86 87 func getBlockDevices(r *parser.Resource) []*ec2.BlockDevice { 88 var blockDevices []*ec2.BlockDevice 89 90 devicesProp := r.GetProperty("BlockDeviceMappings") 91 92 if devicesProp.IsNil() { 93 return blockDevices 94 } 95 96 for _, d := range devicesProp.AsList() { 97 device := &ec2.BlockDevice{ 98 Metadata: d.Metadata(), 99 Encrypted: d.GetBoolProperty("Ebs.Encrypted"), 100 } 101 102 blockDevices = append(blockDevices, device) 103 } 104 105 return blockDevices 106 }