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  }