Skip to content

Commit

Permalink
Feature/ec2 cog lambda acm cft (#1129)
Browse files Browse the repository at this point in the history
* minor typo fix

* add support for ec2 instance

* add support for:
- ec2 instance
- cognito user pool
- lambda function
- acm certificate

* update map function to add support for resource names

* add support for network interfaces

* add support for following resources:

1. acm certificate
2. cognito user pool
3. instance, network interface
4. lambda function

* add comments to pass validation

* comments for go validation

* minor refactor

* minor refactor
  • Loading branch information
gaurav-gogia authored Jan 31, 2022
1 parent ae4eccb commit 14a634b
Show file tree
Hide file tree
Showing 10 changed files with 361 additions and 7 deletions.
15 changes: 13 additions & 2 deletions pkg/mapper/iac-providers/cft/cft.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ import (
"errors"

"github.com/awslabs/goformation/v4/cloudformation/autoscaling"
"github.com/awslabs/goformation/v4/cloudformation/certificatemanager"
"github.com/awslabs/goformation/v4/cloudformation/cloudfront"
"github.com/awslabs/goformation/v4/cloudformation/cloudtrail"
"github.com/awslabs/goformation/v4/cloudformation/cognito"
"github.com/awslabs/goformation/v4/cloudformation/lambda"
"github.com/awslabs/goformation/v4/cloudformation/sns"
"github.com/awslabs/goformation/v4/cloudformation/sqs"

Expand Down Expand Up @@ -85,7 +88,7 @@ func (m cftMapper) Map(resource interface{}, params ...map[string]interface{}) (
return nil, errors.New(errUnsupportedDoc)
}
for name, untypedRes := range template.Resources {
for _, resourceConfig := range m.mapConfigForResource(untypedRes) {
for _, resourceConfig := range m.mapConfigForResource(untypedRes, name) {
if resourceConfig.Resource != nil {
config := output.ResourceConfig{
Name: name,
Expand Down Expand Up @@ -125,7 +128,7 @@ func (m cftMapper) Map(resource interface{}, params ...map[string]interface{}) (
return configs, nil
}

func (m cftMapper) mapConfigForResource(r cloudformation.Resource) []config.AWSResourceConfig {
func (m cftMapper) mapConfigForResource(r cloudformation.Resource, resourceName string) []config.AWSResourceConfig {
switch resource := r.(type) {
case *docdb.DBCluster:
return config.GetDocDBConfig(resource)
Expand Down Expand Up @@ -227,6 +230,14 @@ func (m cftMapper) mapConfigForResource(r cloudformation.Resource) []config.AWSR
return config.GetSnsTopicPolicyConfig(resource)
case *autoscaling.LaunchConfiguration:
return config.GetAutoScalingLaunchConfigurationConfig(resource)
case *ec2.Instance:
return config.GetEC2InstanceConfig(resource, resourceName)
case *cognito.UserPool:
return config.GetCognitoUserPoolConfig(resource)
case *lambda.Function:
return config.GetLambdaFunctionConfig(resource)
case *certificatemanager.Certificate:
return config.GetCertificateManagerCertificateConfig(resource)
default:
}
return []config.AWSResourceConfig{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ import (
"github.com/awslabs/goformation/v4/cloudformation/autoscaling"
)

// EbsBlockDeviceBlock hold config for EbsBlockDevice
// EbsBlockDeviceBlock holds config for EbsBlockDevice
type EbsBlockDeviceBlock struct {
DeviceName string `json:"device_name"`
Encrypted bool `json:"encrypted"`
DeleteOnTermination bool `json:"delete_on_termination"`
}

// MetadataOptionsBlock hold config for MetadataOptions
// MetadataOptionsBlock holds config for MetadataOptions
type MetadataOptionsBlock struct {
HTTPEndpoint string `json:"http_endpoint"`
HTTPTokens string `json:"http_tokens"`
}

// AutoScalingLaunchConfigurationConfig hold config for AutoScalingLaunchConfiguration
// AutoScalingLaunchConfigurationConfig holds config for AutoScalingLaunchConfiguration
type AutoScalingLaunchConfigurationConfig struct {
Config
EnableMonitoring bool `json:"enable_monitoring"`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
Copyright (C) 2022 Accurics, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import "github.com/awslabs/goformation/v4/cloudformation/certificatemanager"

// CertificateManagerCertificateConfig holds config for CertificateManagerCertificate
type CertificateManagerCertificateConfig struct {
Config
DomainName string `json:"domain_name"`
ValidationMethod string `json:"validation_method"`
}

// GetCertificateManagerCertificateConfig returns config for CertificateManagerCertificate
func GetCertificateManagerCertificateConfig(c *certificatemanager.Certificate) []AWSResourceConfig {
cf := CertificateManagerCertificateConfig{
Config: Config{
Tags: c.Tags,
},
DomainName: c.DomainName,
ValidationMethod: c.ValidationMethod,
}

return []AWSResourceConfig{{
Resource: cf,
Metadata: c.AWSCloudFormationMetadata,
}}
}
62 changes: 62 additions & 0 deletions pkg/mapper/iac-providers/cft/config/cognito-user-pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Copyright (C) 2022 Accurics, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANT IES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import "github.com/awslabs/goformation/v4/cloudformation/cognito"

// PasswordPolicyBlock holds config for PasswordPolicy
type PasswordPolicyBlock struct {
MinimumLength int `json:"minimum_length"`
RequireLowercase bool `json:"require_lowercase"`
RequireUppercase bool `json:"require_uppercase"`
RequireNumbers bool `json:"require_numbers"`
RequireSymbols bool `json:"require_symbols"`
TemporaryPasswordValidityDays int `json:"temporary_password_validity_days"`
}

// CognitoUserPoolConfig holds config for CognitoUserPool
type CognitoUserPoolConfig struct {
Config
Name string `json:"name"`
PasswordPolicy []PasswordPolicyBlock `json:"password_policy"`
}

// GetCognitoUserPoolConfig returns config for CognitoUserPool
func GetCognitoUserPoolConfig(u *cognito.UserPool) []AWSResourceConfig {
passwordPolicy := make([]PasswordPolicyBlock, 1)
if u.Policies != nil && u.Policies.PasswordPolicy != nil {
passwordPolicy[0].MinimumLength = u.Policies.PasswordPolicy.MinimumLength
passwordPolicy[0].RequireLowercase = u.Policies.PasswordPolicy.RequireLowercase
passwordPolicy[0].RequireUppercase = u.Policies.PasswordPolicy.RequireUppercase
passwordPolicy[0].RequireNumbers = u.Policies.PasswordPolicy.RequireNumbers
passwordPolicy[0].RequireSymbols = u.Policies.PasswordPolicy.RequireSymbols
passwordPolicy[0].TemporaryPasswordValidityDays = u.Policies.PasswordPolicy.TemporaryPasswordValidityDays
}

cf := CognitoUserPoolConfig{
Config: Config{
Name: u.UserPoolName,
},
Name: u.UserPoolName,
PasswordPolicy: passwordPolicy,
}

return []AWSResourceConfig{{
Resource: cf,
Metadata: u.AWSCloudFormationMetadata,
}}
}
121 changes: 121 additions & 0 deletions pkg/mapper/iac-providers/cft/config/ec2-instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
Copyright (C) 2022 Accurics, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package config

import (
"fmt"
"strconv"

"github.com/accurics/terrascan/pkg/mapper/iac-providers/cft/store"
"github.com/awslabs/goformation/v4/cloudformation/ec2"
)

// GetNetworkInterface represents subresource aws_network_interface for NetworkInterface attribute
const (
GetNetworkInterface = "NetworkInterface"
)

// AttachmentBlock holds config for Attachment
type AttachmentBlock struct {
Instance string `json:"instance"`
DeviceIndex int `json:"device_index"`
}

// NetworkInterfaceConfig holds config for NetworkInterface
type NetworkInterfaceConfig struct {
Config
SubnetID string `json:"subnet_id"`
PrivateIPs []string `json:"private_ips"`
Attachment []AttachmentBlock `json:"attachment"`
}

// NetworkInterfaceBlock holds config for NetworkInterface
type NetworkInterfaceBlock struct {
NetworkInterfaceID string `json:"network_interface_id"`
DeviceIndex int `json:"device_index"`
DeleteOnTermination bool `json:"delete_on_termination"`
}

// EC2InstanceConfig holds config for EC2Instance
type EC2InstanceConfig struct {
Config
AMI string `json:"ami"`
InstanceType string `json:"instance_type"`
EBSOptimized bool `json:"ebs_optimized"`
Hibernation bool `json:"hibernation"`
Monitoring bool `json:"monitoring"`
IAMInstanceProfile string `json:"iam_instance_profile"`
VPCSecurityGroupIDs []string `json:"vpc_security_group_ids"`
NetworkInterface []NetworkInterfaceBlock `json:"network_interface"`
}

// GetEC2InstanceConfig returns config for EC2Instance
func GetEC2InstanceConfig(i *ec2.Instance, instanceName string) []AWSResourceConfig {
nics := make([]NetworkInterfaceBlock, len(i.NetworkInterfaces))
niconfigs := make([]NetworkInterfaceConfig, len(i.NetworkInterfaces))
awsconfig := make([]AWSResourceConfig, len(i.NetworkInterfaces))

for index := range i.NetworkInterfaces {
nics[index].NetworkInterfaceID = i.NetworkInterfaces[index].NetworkInterfaceId
nics[index].DeleteOnTermination = i.NetworkInterfaces[index].DeleteOnTermination
var devindex int
devindex, err := strconv.Atoi(i.NetworkInterfaces[index].DeviceIndex)
if err != nil {
devindex = 0
}
nics[index].DeviceIndex = devindex

// create aws_network_interface resource on the fly for every network interface used in aws_instance
niconfigs[index].SubnetID = i.NetworkInterfaces[index].SubnetId
if i.NetworkInterfaces[index].PrivateIpAddress != "" {
niconfigs[index].PrivateIPs = []string{i.NetworkInterfaces[index].PrivateIpAddress}
}

nicname := fmt.Sprintf("%s%d", instanceName, index)
niconfigs[index].Attachment = make([]AttachmentBlock, 1)
niconfigs[index].Attachment[0].DeviceIndex = devindex
niconfigs[index].Attachment[0].Instance = store.AwsEc2Instance + "." + instanceName
niconfigs[index].Config.Name = nicname

awsconfig[index].Type = GetNetworkInterface
awsconfig[index].Name = nicname
awsconfig[index].Resource = niconfigs[index]
awsconfig[index].Metadata = i.AWSCloudFormationMetadata
}

ec2Config := EC2InstanceConfig{
Config: Config{
Tags: i.Tags,
Name: instanceName,
},
AMI: i.ImageId,
InstanceType: i.InstanceType,
EBSOptimized: i.EbsOptimized,
Hibernation: i.HibernationOptions.Configured,
Monitoring: i.Monitoring,
IAMInstanceProfile: i.IamInstanceProfile,
VPCSecurityGroupIDs: i.SecurityGroupIds,
NetworkInterface: nics,
}

var awsconfigec2 AWSResourceConfig
awsconfigec2.Resource = ec2Config
awsconfigec2.Metadata = i.AWSCloudFormationMetadata
awsconfig = append(awsconfig, awsconfigec2)

return awsconfig
}
Loading

0 comments on commit 14a634b

Please sign in to comment.