Repository: cycloidio/terracost
Pull request #97 (2023-06-06 06:49:23)

aws: add new resource such eks


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 584be9a..828f4c2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
 
 ### Added
 
+- AWS support for `aws_eks_cluster`, `aws_eks_node_group`, `aws_efs_file_system`
+  ([Pull #97](https://github.com/cycloidio/terracost/pull/97))
 - Support for remote module references
   ([Issue #88](https://github.com/cycloidio/terracost/issues/88))
 - Added 'Usage' support for those options that are not from configuration but from usage of the resource
diff --git a/aws/field/field.go b/aws/field/field.go
index 4bf0eeb..04bc689 100644
--- a/aws/field/field.go
+++ b/aws/field/field.go
@@ -22,6 +22,11 @@ const (
 	VolumeAPIName                // Volume API Name
 	VolumeType                   // Volume Type
 
+	// EFSFileSystem
+	StorageClass    // Storage Class
+	AccessType      // Access Type
+	ThroughputClass // Throughput Class
+
 	// ElastiCache
 	CacheEngine // Cache Engine
 
diff --git a/aws/field/field_gen.go b/aws/field/field_gen.go
index 6c43dd9..7cdaf92 100644
--- a/aws/field/field_gen.go
+++ b/aws/field/field_gen.go
@@ -7,11 +7,11 @@ import (
 	"strings"
 )
 
-const _FieldName = "SKUCapacityStatusGroupInstance TypeLocationOperating SystemPre Installed S/WProduct FamilyserviceCodeTenancyusageTypeVolume API NameVolume TypeCache EngineDatabase EngineDatabase EditionDeployment OptionLicense ModelCurrencyPricePerUnitStartingRangeTermTypeUnit"
+const _FieldName = "SKUCapacityStatusGroupInstance TypeLocationOperating SystemPre Installed S/WProduct FamilyserviceCodeTenancyusageTypeVolume API NameVolume TypeStorage ClassAccess TypeThroughput ClassCache EngineDatabase EngineDatabase EditionDeployment OptionLicense ModelCurrencyPricePerUnitStartingRangeTermTypeUnit"
 
-var _FieldIndex = [...]uint16{0, 3, 17, 22, 35, 43, 59, 76, 90, 101, 108, 117, 132, 143, 155, 170, 186, 203, 216, 224, 236, 249, 257, 261}
+var _FieldIndex = [...]uint16{0, 3, 17, 22, 35, 43, 59, 76, 90, 101, 108, 117, 132, 143, 156, 167, 183, 195, 210, 226, 243, 256, 264, 276, 289, 297, 301}
 
-const _FieldLowerName = "skucapacitystatusgroupinstance typelocationoperating systempre installed s/wproduct familyservicecodetenancyusagetypevolume api namevolume typecache enginedatabase enginedatabase editiondeployment optionlicense modelcurrencypriceperunitstartingrangetermtypeunit"
+const _FieldLowerName = "skucapacitystatusgroupinstance typelocationoperating systempre installed s/wproduct familyservicecodetenancyusagetypevolume api namevolume typestorage classaccess typethroughput classcache enginedatabase enginedatabase editiondeployment optionlicense modelcurrencypriceperunitstartingrangetermtypeunit"
 
 func (i Field) String() string {
 	if i >= Field(len(_FieldIndex)-1) {
@@ -37,19 +37,22 @@ func _FieldNoOp() {
 	_ = x[UsageType-(10)]
 	_ = x[VolumeAPIName-(11)]
 	_ = x[VolumeType-(12)]
-	_ = x[CacheEngine-(13)]
-	_ = x[DatabaseEngine-(14)]
-	_ = x[DatabaseEdition-(15)]
-	_ = x[DeploymentOption-(16)]
-	_ = x[LicenseModel-(17)]
-	_ = x[Currency-(18)]
-	_ = x[PricePerUnit-(19)]
-	_ = x[StartingRange-(20)]
-	_ = x[TermType-(21)]
-	_ = x[Unit-(22)]
+	_ = x[StorageClass-(13)]
+	_ = x[AccessType-(14)]
+	_ = x[ThroughputClass-(15)]
+	_ = x[CacheEngine-(16)]
+	_ = x[DatabaseEngine-(17)]
+	_ = x[DatabaseEdition-(18)]
+	_ = x[DeploymentOption-(19)]
+	_ = x[LicenseModel-(20)]
+	_ = x[Currency-(21)]
+	_ = x[PricePerUnit-(22)]
+	_ = x[StartingRange-(23)]
+	_ = x[TermType-(24)]
+	_ = x[Unit-(25)]
 }
 
-var _FieldValues = []Field{SKU, CapacityStatus, Group, InstanceType, Location, OperatingSystem, PreInstalledSW, ProductFamily, ServiceCode, Tenancy, UsageType, VolumeAPIName, VolumeType, CacheEngine, DatabaseEngine, DatabaseEdition, DeploymentOption, LicenseModel, Currency, PricePerUnit, StartingRange, TermType, Unit}
+var _FieldValues = []Field{SKU, CapacityStatus, Group, InstanceType, Location, OperatingSystem, PreInstalledSW, ProductFamily, ServiceCode, Tenancy, UsageType, VolumeAPIName, VolumeType, StorageClass, AccessType, ThroughputClass, CacheEngine, DatabaseEngine, DatabaseEdition, DeploymentOption, LicenseModel, Currency, PricePerUnit, StartingRange, TermType, Unit}
 
 var _FieldNameToValueMap = map[string]Field{
 	_FieldName[0:3]:          SKU,
@@ -78,26 +81,32 @@ var _FieldNameToValueMap = map[string]Field{
 	_FieldLowerName[117:132]: VolumeAPIName,
 	_FieldName[132:143]:      VolumeType,
 	_FieldLowerName[132:143]: VolumeType,
-	_FieldName[143:155]:      CacheEngine,
-	_FieldLowerName[143:155]: CacheEngine,
-	_FieldName[155:170]:      DatabaseEngine,
-	_FieldLowerName[155:170]: DatabaseEngine,
-	_FieldName[170:186]:      DatabaseEdition,
-	_FieldLowerName[170:186]: DatabaseEdition,
-	_FieldName[186:203]:      DeploymentOption,
-	_FieldLowerName[186:203]: DeploymentOption,
-	_FieldName[203:216]:      LicenseModel,
-	_FieldLowerName[203:216]: LicenseModel,
-	_FieldName[216:224]:      Currency,
-	_FieldLowerName[216:224]: Currency,
-	_FieldName[224:236]:      PricePerUnit,
-	_FieldLowerName[224:236]: PricePerUnit,
-	_FieldName[236:249]:      StartingRange,
-	_FieldLowerName[236:249]: StartingRange,
-	_FieldName[249:257]:      TermType,
-	_FieldLowerName[249:257]: TermType,
-	_FieldName[257:261]:      Unit,
-	_FieldLowerName[257:261]: Unit,
+	_FieldName[143:156]:      StorageClass,
+	_FieldLowerName[143:156]: StorageClass,
+	_FieldName[156:167]:      AccessType,
+	_FieldLowerName[156:167]: AccessType,
+	_FieldName[167:183]:      ThroughputClass,
+	_FieldLowerName[167:183]: ThroughputClass,
+	_FieldName[183:195]:      CacheEngine,
+	_FieldLowerName[183:195]: CacheEngine,
+	_FieldName[195:210]:      DatabaseEngine,
+	_FieldLowerName[195:210]: DatabaseEngine,
+	_FieldName[210:226]:      DatabaseEdition,
+	_FieldLowerName[210:226]: DatabaseEdition,
+	_FieldName[226:243]:      DeploymentOption,
+	_FieldLowerName[226:243]: DeploymentOption,
+	_FieldName[243:256]:      LicenseModel,
+	_FieldLowerName[243:256]: LicenseModel,
+	_FieldName[256:264]:      Currency,
+	_FieldLowerName[256:264]: Currency,
+	_FieldName[264:276]:      PricePerUnit,
+	_FieldLowerName[264:276]: PricePerUnit,
+	_FieldName[276:289]:      StartingRange,
+	_FieldLowerName[276:289]: StartingRange,
+	_FieldName[289:297]:      TermType,
+	_FieldLowerName[289:297]: TermType,
+	_FieldName[297:301]:      Unit,
+	_FieldLowerName[297:301]: Unit,
 }
 
 var _FieldNames = []string{
@@ -114,16 +123,19 @@ var _FieldNames = []string{
 	_FieldName[108:117],
 	_FieldName[117:132],
 	_FieldName[132:143],
-	_FieldName[143:155],
-	_FieldName[155:170],
-	_FieldName[170:186],
-	_FieldName[186:203],
-	_FieldName[203:216],
-	_FieldName[216:224],
-	_FieldName[224:236],
-	_FieldName[236:249],
-	_FieldName[249:257],
-	_FieldName[257:261],
+	_FieldName[143:156],
+	_FieldName[156:167],
+	_FieldName[167:183],
+	_FieldName[183:195],
+	_FieldName[195:210],
+	_FieldName[210:226],
+	_FieldName[226:243],
+	_FieldName[243:256],
+	_FieldName[256:264],
+	_FieldName[264:276],
+	_FieldName[276:289],
+	_FieldName[289:297],
+	_FieldName[297:301],
 }
 
 // FieldString retrieves an enum value from the enum constants string name.
diff --git a/aws/filter.go b/aws/filter.go
index 548cd76..083cd35 100644
--- a/aws/filter.go
+++ b/aws/filter.go
@@ -26,6 +26,10 @@ func MinimalFilter(pp *price.WithProduct) bool {
 		return true // is minimal already
 	case "AmazonCloudWatch":
 		return true // is minimal already
+	case "AmazonEKS":
+		return true // is minimal already
+	case "AmazonEFS":
+		return true // is minimal already
 	default:
 		return false
 	}
diff --git a/aws/ingester.go b/aws/ingester.go
index c6a4060..959931f 100644
--- a/aws/ingester.go
+++ b/aws/ingester.go
@@ -201,6 +201,11 @@ var columnProductToIngest = map[field.Field]string{
 	field.VolumeAPIName:   "VolumeAPIName",
 	field.VolumeType:      "VolumeType",
 
+	// EFS attributes
+	field.StorageClass:    "StorageClass",
+	field.AccessType:      "AccessType",
+	field.ThroughputClass: "ThroughputClass",
+
 	// ElastiCache
 	field.CacheEngine: "CacheEngine",
 
diff --git a/aws/services.go b/aws/services.go
index 3cbc632..3a95a7f 100644
--- a/aws/services.go
+++ b/aws/services.go
@@ -3,10 +3,12 @@ package aws
 // SupportedServices is a list of all AWS services that are supported by Terracost.
 var supportedServices = map[string]struct{}{
 	"AmazonEC2":         {},
+	"AmazonEFS":         {},
+	"AmazonEKS":         {},
 	"AmazonRDS":         {},
-	"AWSELB":            {},
 	"AmazonElastiCache": {},
 	"AmazonCloudWatch":  {},
+	"AWSELB":            {},
 }
 
 // IsServiceSupported returns true if the AWS service is valid and supported by Terracost (e.g. for ingestion.)
diff --git a/aws/terraform/efs_file_system.go b/aws/terraform/efs_file_system.go
new file mode 100644
index 0000000..96c8220
--- /dev/null
+++ b/aws/terraform/efs_file_system.go
@@ -0,0 +1,223 @@
+package terraform
+
+import (
+	"fmt"
+
+	"github.com/mitchellh/mapstructure"
+	"github.com/shopspring/decimal"
+
+	"github.com/cycloidio/terracost/aws/region"
+	"github.com/cycloidio/terracost/product"
+	"github.com/cycloidio/terracost/query"
+	"github.com/cycloidio/terracost/terraform"
+	"github.com/cycloidio/terracost/util"
+)
+
+// EFSFileSystem represents an EFS that can be cost-estimated.
+type EFSFileSystem struct {
+	provider                     *Provider
+	region                       region.Code
+	availabilityZoneName         string
+	throughputMode               string
+	provisionedThroughputInMibps decimal.Decimal
+
+	// Usage
+	hasLifecyclePolicy             bool
+	storageGB                      decimal.Decimal
+	infrequentAccessStorageGB      decimal.Decimal
+	monthlyInfrequentAccessReadGB  decimal.Decimal
+	monthlyInfrequentAccessWriteGB decimal.Decimal
+}
+
+// efsFileSystemValues represents the structure of Terraform values for aws_efs_file_system resource.
+type efsFileSystemValues struct {
+	AvailabilityZoneName string `mapstructure:"availability_zone_name"`
+	LifecyclePolicy      []struct {
+		TransitionToIa                  string `mapstructure:"transition_to_ia"`
+		TransitionToPrimaryStorageClass string `mapstructure:"transition_to_primary_storage_class"`
+	} `mapstructure:"lifecycle_policy"`
+	ThroughputMode string `mapstructure:"throughput_mode"`
+	// only available if ThroughputMode=provisioned
+	ProvisionedThroughputInMibps float64 `mapstructure:"provisioned_throughput_in_mibps"`
+
+	Usage struct {
+		StorageGB                      float64 `mapstructure:"storage_gb"`
+		InfrequentAccessStorageGB      float64 `mapstructure:"infrequent_access_storage_gb"`
+		MonthlyInfrequentAccessReadGB  float64 `mapstructure:"monthly_infrequent_access_read_gb"`
+		MonthlyInfrequentAccessWriteGB float64 `mapstructure:"monthly_infrequent_access_write_gb"`
+	} `mapstructure:"tc_usage"`
+}
+
+// decodeEFSFileSystemValues decodes and returns efsFileSystemValues from a Terraform values map.
+func decodeEFSFileSystemValues(tfVals map[string]interface{}) (efsFileSystemValues, error) {
+	var v efsFileSystemValues
+	config := &mapstructure.DecoderConfig{
+		WeaklyTypedInput: true,
+		Result:           &v,
+	}
+
+	decoder, err := mapstructure.NewDecoder(config)
+	if err != nil {
+		return v, err
+	}
+
+	if err := decoder.Decode(tfVals); err != nil {
+		return v, err
+	}
+	return v, nil
+}
+
+// newEFSFileSystem creates a new EFSFileSystem from efsFileSystemValues.
+func (p *Provider) newEFSFileSystem(rss map[string]terraform.Resource, vals efsFileSystemValues) *EFSFileSystem {
+	v := &EFSFileSystem{
+		provider:       p,
+		region:         p.region,
+		throughputMode: "bursting",
+		// only available if ThroughputMode=provisioned
+		provisionedThroughputInMibps: decimal.NewFromFloat(0),
+		hasLifecyclePolicy:           false,
+		// From Usage
+		storageGB:                      decimal.NewFromFloat(vals.Usage.StorageGB),
+		infrequentAccessStorageGB:      decimal.NewFromFloat(vals.Usage.InfrequentAccessStorageGB),
+		monthlyInfrequentAccessReadGB:  decimal.NewFromFloat(vals.Usage.MonthlyInfrequentAccessReadGB),
+		monthlyInfrequentAccessWriteGB: decimal.NewFromFloat(vals.Usage.MonthlyInfrequentAccessWriteGB),
+	}
+
+	if reg := region.NewFromZone(vals.AvailabilityZoneName); reg.Valid() {
+		v.region = reg
+		v.availabilityZoneName = vals.AvailabilityZoneName
+	}
+
+	if len(vals.LifecyclePolicy) > 0 {
+		v.hasLifecyclePolicy = true
+	}
+
+	if vals.ThroughputMode != "" {
+		v.throughputMode = vals.ThroughputMode
+	}
+
+	if vals.ThroughputMode == "provisioned" {
+		if vals.ProvisionedThroughputInMibps > 0 {
+			v.provisionedThroughputInMibps = v.calculateProvisionedThroughput(v.storageGB, decimal.NewFromFloat(vals.ProvisionedThroughputInMibps))
+		}
+	}
+
+	return v
+}
+
+func (v *EFSFileSystem) calculateProvisionedThroughput(storageGB decimal.Decimal, throughput decimal.Decimal) decimal.Decimal {
+	defaultThroughput := storageGB.Mul(decimal.NewFromInt(730).Div(decimal.NewFromInt(20).Mul(decimal.NewFromInt(1))))
+	totalProvisionedThroughput := throughput.Mul(decimal.NewFromInt(730))
+	totalBillableProvisionedThroughput := totalProvisionedThroughput.Sub(defaultThroughput).Div(decimal.NewFromInt(730))
+
+	//spew.Dump(storageGB, throughput, defaultThroughput, totalProvisionedThroughput, totalBillableProvisionedThroughput)
+	if totalBillableProvisionedThroughput.IsPositive() {
+		//spew.Dump(totalBillableProvisionedThroughput)
+		//spew.Dump(decimal.NewFromFloat(float64(8.5)))
+		//spew.Dump(reflect.DeepEqual(decimal.NewFromFloat(float64(8.5)), decimal.NewFromFloat(float64(8.5))))
+		return totalBillableProvisionedThroughput
+	}
+
+	return decimal.Zero
+}
+
+// Components returns the price component queries that make up the EFSFileSystem.
+func (v *EFSFileSystem) Components() []query.Component {
+	usagetype := ".*-TimedStorage-ByteHrs"
+	if v.availabilityZoneName != "" {
+		usagetype = ".*-TimedStorage-Z-ByteHrs"
+	}
+
+	components := []query.Component{v.efsFileSystemComponent(usagetype, v.storageGB)}
+
+	if v.provisionedThroughputInMibps.GreaterThan(decimal.NewFromInt(0)) {
+		components = append(components, v.provisionedThroughputComponent())
+	}
+
+	if v.hasLifecyclePolicy {
+		usagetype = ".*-IATimedStorage-ByteHrs"
+		if v.availabilityZoneName != "" {
+			usagetype = ".*-IATimedStorage-Z-ByteHrs"
+		}
+
+		if v.infrequentAccessStorageGB.GreaterThan(decimal.NewFromInt(0)) {
+			components = append(components, v.efsFileSystemComponent(usagetype, v.infrequentAccessStorageGB))
+		}
+
+		if v.monthlyInfrequentAccessReadGB.GreaterThan(decimal.NewFromInt(0)) {
+			components = append(components, v.requestsComponent("Read"))
+		}
+
+		if v.monthlyInfrequentAccessWriteGB.GreaterThan(decimal.NewFromInt(0)) {
+			components = append(components, v.requestsComponent("Write"))
+		}
+
+	}
+
+	return components
+}
+
+func (v *EFSFileSystem) efsFileSystemComponent(usagetype string, storageGB decimal.Decimal) query.Component {
+	return query.Component{
+		Name:            fmt.Sprintf("Storage %s", usagetype),
+		MonthlyQuantity: storageGB,
+		Unit:            "GB",
+		Details:         []string{"EFS storage", usagetype},
+		Usage:           true,
+		ProductFilter: &product.Filter{
+			Provider: util.StringPtr(v.provider.key),
+			Service:  util.StringPtr("AmazonEFS"),
+			Family:   util.StringPtr("Storage"),
+			Location: util.StringPtr(v.region.String()),
+			AttributeFilters: []*product.AttributeFilter{
+				{Key: "UsageType", ValueRegex: util.StringPtr(fmt.Sprintf("%s", usagetype))},
+			},
+		},
+	}
+}
+
+func (v *EFSFileSystem) provisionedThroughputComponent() query.Component {
+	return query.Component{
+		Name:            "Provisioned throughput",
+		MonthlyQuantity: v.provisionedThroughputInMibps,
+		Unit:            "MBps",
+		Details:         []string{"Througput"},
+		Usage:           true,
+		ProductFilter: &product.Filter{
+			Provider: util.StringPtr(v.provider.key),
+			Service:  util.StringPtr("AmazonEFS"),
+			Family:   util.StringPtr("Provisioned Throughput"),
+			Location: util.StringPtr(v.region.String()),
+			AttributeFilters: []*product.AttributeFilter{
+				{Key: "UsageType", ValueRegex: util.StringPtr("ProvisionedTP-MiBpsHrs")},
+			},
+		},
+	}
+}
+
+func (v *EFSFileSystem) requestsComponent(accessType string) query.Component {
+	var requestsGB decimal.Decimal
+	if accessType == "Read" {
+		requestsGB = v.monthlyInfrequentAccessReadGB
+	} else {
+		requestsGB = v.monthlyInfrequentAccessWriteGB
+	}
+
+	return query.Component{
+		Name:            fmt.Sprintf("Requests %s", accessType),
+		MonthlyQuantity: requestsGB,
+		Unit:            "GB",
+		Details:         []string{"Requests", "Infrequent Access", accessType},
+		Usage:           true,
+		ProductFilter: &product.Filter{
+			Provider: util.StringPtr(v.provider.key),
+			Service:  util.StringPtr("AmazonEFS"),
+			Family:   util.StringPtr("Storage"),
+			Location: util.StringPtr(v.region.String()),
+			AttributeFilters: []*product.AttributeFilter{
+				{Key: "AccessType", Value: util.StringPtr(accessType)},
+				{Key: "StorageClass", Value: util.StringPtr("Infrequent Access")},
+			},
+		},
+	}
+}
diff --git a/aws/terraform/eks_cluster.go b/aws/terraform/eks_cluster.go
new file mode 100644
index 0000000..964e00b
--- /dev/null
+++ b/aws/terraform/eks_cluster.go
@@ -0,0 +1,105 @@
+package terraform
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/mitchellh/mapstructure"
+	"github.com/shopspring/decimal"
+
+	"github.com/cycloidio/terracost/aws/region"
+	"github.com/cycloidio/terracost/price"
+	"github.com/cycloidio/terracost/product"
+	"github.com/cycloidio/terracost/query"
+	"github.com/cycloidio/terracost/util"
+)
+
+// EKSCluster represents an EKSCluster instance definition that can be cost-estimated.
+type EKSCluster struct {
+	providerKey string
+	region      region.Code
+
+	// tenancy describes the tenancy of an instance.
+	// Valid values include: Shared, Dedicated, Host.
+	// Note: only "Shared" and "Dedicated" are supported at the moment.
+	// Seems only used with fargate
+	// tenancy string
+}
+
+type eKSClusterValues struct {
+	// VpcConfig 						string `mapstructure:"vpc_config "`
+}
+
+func decodeEKSClusterValues(tfVals map[string]interface{}) (eKSClusterValues, error) {
+	var v eKSClusterValues
+	config := &mapstructure.DecoderConfig{
+		WeaklyTypedInput: true,
+		Result:           &v,
+	}
+
+	decoder, err := mapstructure.NewDecoder(config)
+	if err != nil {
+		return v, err
+	}
+
+	if err := decoder.Decode(tfVals); err != nil {
+		return v, err
+	}
+	return v, nil
+}
+
+// NewInstance creates a new Instance from Terraform values.
+func (p *Provider) newEKSCluster(vals eKSClusterValues) *EKSCluster {
+	inst := &EKSCluster{
+		providerKey: p.key,
+		region:      p.region,
+		// tenancy:     "Shared",
+	}
+
+	return inst
+}
+
+// Components returns the price component queries that make up this Instance.
+func (inst *EKSCluster) Components() []query.Component {
+	components := []query.Component{inst.eKSClusterInstanceComponent()}
+
+	return components
+}
+
+func (inst *EKSCluster) eKSClusterInstanceComponent() query.Component {
+
+	// EU-AmazonEKS-Hours:perCluster
+	// Get us-east-1
+	// Convert to USE1
+
+	// eu-west-1 is the only exception where it need to be EU only
+	region := ""
+	if inst.region.String() == "eu-west-1" {
+		region = "EU"
+	} else {
+		splitedRegion := strings.Split(inst.region.String(), "-")
+		region = fmt.Sprintf("%s%s%s", strings.ToUpper(splitedRegion[0]), strings.ToUpper(splitedRegion[1][0:1]), splitedRegion[2])
+	}
+
+	return query.Component{
+		Name:           "EKS Cluster",
+		Details:        []string{"EKSCluster:Compute"},
+		HourlyQuantity: decimal.NewFromInt(1),
+		ProductFilter: &product.Filter{
+			Provider: util.StringPtr(inst.providerKey),
+			Service:  util.StringPtr("AmazonEKS"),
+			Family:   util.StringPtr("Compute"),
+			Location: util.StringPtr(inst.region.String()),
+			AttributeFilters: []*product.AttributeFilter{
+				// {Key: "Tenancy", Value: util.StringPtr(inst.tenancy)},
+				{Key: "UsageType", Value: util.StringPtr(fmt.Sprintf("%s-AmazonEKS-Hours:perCluster", region))},
+			},
+		},
+		PriceFilter: &price.Filter{
+			// Unit: util.StringPtr("Hours"),
+			AttributeFilters: []*price.AttributeFilter{
+				{Key: "TermType", Value: util.StringPtr("OnDemand")},
+			},
+		},
+	}
+}
diff --git a/aws/terraform/eks_node_group.go b/aws/terraform/eks_node_group.go
new file mode 100644
index 0000000..d5c3d09
--- /dev/null
+++ b/aws/terraform/eks_node_group.go
@@ -0,0 +1,158 @@
+package terraform
+
+import (
+	"fmt"
+
+	"github.com/mitchellh/mapstructure"
+	"github.com/shopspring/decimal"
+
+	"github.com/cycloidio/terracost/aws/region"
+	"github.com/cycloidio/terracost/terraform"
+)
+
+// eksNodeGroup represents the structure of Terraform values for autoscaling_group resource.
+type eksNodeGroupValues struct {
+	ScalingConfig []struct {
+		MinSize         int64 `mapstructure:"min_size"`
+		DesiredCapacity int64 `mapstructure:"desired_size"`
+	} `mapstructure:"scaling_config"`
+
+	InstanceTypes []string `mapstructure:"instance_types"`
+	DiskSize      float64  `mapstructure:"disk_size"`
+
+	LaunchTemplate []struct {
+		ID      string `mapstructure:"id"`
+		Name    string `mapstructure:"name"`
+		Version string `mapstructure:"version"`
+	} `mapstructure:"launch_template"`
+}
+
+// decodeEKSNodeGroupValues decodes and returns instanceValues from a Terraform values map.
+func decodeEKSNodeGroupValues(tfVals map[string]interface{}) (eksNodeGroupValues, error) {
+	var v eksNodeGroupValues
+	config := &mapstructure.DecoderConfig{
+		WeaklyTypedInput: true,
+		Result:           &v,
+	}
+
+	decoder, err := mapstructure.NewDecoder(config)
+	if err != nil {
+		return v, err
+	}
+
+	if err := decoder.Decode(tfVals); err != nil {
+		return v, err
+	}
+	return v, nil
+}
+
+// newInstance creates a new Instance from instanceValues.
+func (p *Provider) newEKSNodeGroup(rss map[string]terraform.Resource, vals eksNodeGroupValues) *Instance {
+
+	inst := &Instance{
+		provider: p,
+		region:   p.region,
+		tenancy:  "Shared",
+
+		// Note: every Instance is estimated as a Linux without pre-installed S/W
+		operatingSystem: "Linux",
+		capacityStatus:  "Used",
+		preInstalledSW:  "NA",
+	}
+
+	var defaultEKSInstanceType = "t3.medium"
+	var availabilityZone = fmt.Sprintf("%s%s", p.region, "a")
+	var instanceCount int64
+	if len(vals.ScalingConfig) > 0 {
+		if vals.ScalingConfig[0].DesiredCapacity > 0 {
+			instanceCount = vals.ScalingConfig[0].DesiredCapacity
+		} else if vals.ScalingConfig[0].MinSize > 0 {
+			instanceCount = vals.ScalingConfig[0].MinSize
+		} else {
+			instanceCount = 1
+		}
+	}
+	inst.instanceCount = decimal.NewFromInt(instanceCount)
+
+	if len(vals.LaunchTemplate) > 0 {
+		// If LT defined
+		var ltref string
+		if len(vals.LaunchTemplate) > 0 {
+			if len(vals.LaunchTemplate[0].ID) > 0 {
+				ltref = vals.LaunchTemplate[0].ID
+			} else {
+				ltref = vals.LaunchTemplate[0].Name
+			}
+		}
+
+		lt, err := decodeLaunchTemplateValues(rss[ltref].Values)
+		if err != nil {
+			return inst
+		}
+
+		inst.instanceType = lt.InstanceType
+		if len(lt.Placement) > 0 {
+			if lt.Placement[0].Tenancy == "dedicated" {
+				inst.tenancy = "Dedicated"
+			}
+			if lt.Placement[0].AvailabilityZone != "" {
+				availabilityZone = lt.Placement[0].AvailabilityZone
+			}
+		}
+
+		if lt.EBSOptimized {
+			inst.ebsOptimized = true
+		}
+
+		if len(lt.CreditSpecification) > 0 {
+			creditspec := lt.CreditSpecification[0]
+			if creditspec.CPUCredits == "unlimited" {
+				inst.cpuCredits = true
+			}
+		}
+
+		if len(lt.Monitoring) > 0 {
+			monitoring := lt.Monitoring[0]
+			if monitoring.Enabled {
+				inst.enableMonitoring = true
+			}
+		}
+
+		// We assume the first EBS defined correspond to the RootDevice
+		if len(lt.BlockDeviceMappings) > 0 {
+			if len(lt.BlockDeviceMappings[0].EBS) > 0 {
+				rbd := lt.BlockDeviceMappings[0].EBS[0]
+				volVals := volumeValues{AvailabilityZone: availabilityZone}
+				volVals.Type = rbd.VolumeType
+				volVals.Size = rbd.VolumeSize
+				volVals.IOPS = rbd.IOPS
+				inst.rootVolume = p.newVolume(volVals)
+			}
+		}
+	} else {
+		// If no LT
+		if len(vals.InstanceTypes) > 0 {
+			inst.instanceType = vals.InstanceTypes[0]
+		} else {
+			inst.instanceType = defaultEKSInstanceType
+		}
+
+		// Set the default Linux size
+		disksize := float64(20)
+		if vals.DiskSize > 0 {
+			disksize = vals.DiskSize
+		}
+
+		volVals := volumeValues{AvailabilityZone: availabilityZone}
+		volVals.Type = "gp3"
+		volVals.Size = disksize
+		inst.rootVolume = p.newVolume(volVals)
+	}
+
+	// Override provider region by the one defined in LC/LT
+	if reg := region.NewFromZone(availabilityZone); reg.Valid() {
+		inst.region = reg
+	}
+
+	return inst
+}
diff --git a/aws/terraform/provider.go b/aws/terraform/provider.go
index 41de1d9..7ad4ad5 100644
--- a/aws/terraform/provider.go
+++ b/aws/terraform/provider.go
@@ -34,7 +34,6 @@ func (p *Provider) ResourceComponents(rss map[string]terraform.Resource, tfRes t
 		if err != nil {
 			return nil
 		}
-
 		return p.newInstance(vals).Components()
 	case "aws_autoscaling_group":
 		vals, err := decodeAutoscalingGroupValues(tfRes.Values)
@@ -48,6 +47,12 @@ func (p *Provider) ResourceComponents(rss map[string]terraform.Resource, tfRes t
 			return nil
 		}
 		return p.newVolume(vals).Components()
+	case "aws_efs_file_system":
+		vals, err := decodeEFSFileSystemValues(tfRes.Values)
+		if err != nil {
+			return nil
+		}
+		return p.newEFSFileSystem(rss, vals).Components()
 	case "aws_elasticache_cluster":
 		vals, err := decodeElastiCacheValues(tfRes.Values)
 		if err != nil {
@@ -82,6 +87,18 @@ func (p *Provider) ResourceComponents(rss map[string]terraform.Resource, tfRes t
 		// ELB Classic does not have any special configuration.
 		vals := lbValues{LoadBalancerType: "classic"}
 		return p.newLB(vals).Components()
+	case "aws_eks_cluster":
+		vals, err := decodeEKSClusterValues(tfRes.Values)
+		if err != nil {
+			return nil
+		}
+		return p.newEKSCluster(vals).Components()
+	case "aws_eks_node_group":
+		vals, err := decodeEKSNodeGroupValues(tfRes.Values)
+		if err != nil {
+			return nil
+		}
+		return p.newEKSNodeGroup(rss, vals).Components()
 	default:
 		return nil
 	}
diff --git a/aws/terraform/volume.go b/aws/terraform/volume.go
index 99c2a17..b570045 100644
--- a/aws/terraform/volume.go
+++ b/aws/terraform/volume.go
@@ -52,9 +52,9 @@ func (p *Provider) newVolume(vals volumeValues) *Volume {
 	v := &Volume{
 		provider:   p,
 		region:     p.region,
-		volumeType: "gp2",
+		volumeType: "gp3",
 		size:       decimal.NewFromInt(8),
-		iops:       decimal.NewFromInt(100),
+		iops:       decimal.NewFromInt(16000),
 	}
 
 	if reg := region.NewFromZone(vals.AvailabilityZone); reg.Valid() {
diff --git a/azurerm/service_string.go b/azurerm/service_string.go
index ffbe663..f372927 100644
--- a/azurerm/service_string.go
+++ b/azurerm/service_string.go
@@ -44,8 +44,8 @@ func ServiceString(s string) (Service, error) {
 	if val, ok := _ServiceNameToValueMap[s]; ok {
 		return val, nil
 	}
-
-	if val, ok := _ServiceNameToValueMap[strings.ToLower(s)]; ok {
+	s = strings.ToLower(s)
+	if val, ok := _ServiceNameToValueMap[s]; ok {
 		return val, nil
 	}
 	return 0, fmt.Errorf("%s does not belong to Service values", s)
diff --git a/examples/go.mod b/examples/go.mod
index 74ece6e..fe5b875 100644
--- a/examples/go.mod
+++ b/examples/go.mod
@@ -1,6 +1,6 @@
 module github.com/cycloidio/terracost/samples
 
-go 1.17
+go 1.18
 
 require (
 	github.com/cycloidio/terracost v0.5.0
@@ -8,8 +8,11 @@ require (
 )
 
 require (
-	cloud.google.com/go v0.97.0 // indirect
-	cloud.google.com/go/storage v1.10.0 // indirect
+	cloud.google.com/go v0.104.0 // indirect
+	cloud.google.com/go/compute v1.12.1 // indirect
+	cloud.google.com/go/compute/metadata v0.2.1 // indirect
+	cloud.google.com/go/iam v0.3.0 // indirect
+	cloud.google.com/go/storage v1.23.0 // indirect
 	github.com/agext/levenshtein v1.2.3 // indirect
 	github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
 	github.com/apparentlymart/go-versions v1.0.1 // indirect
@@ -21,8 +24,11 @@ require (
 	github.com/fatih/color v1.13.0 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
-	github.com/google/go-cmp v0.5.6 // indirect
-	github.com/googleapis/gax-go/v2 v2.1.1 // indirect
+	github.com/google/go-cmp v0.5.9 // indirect
+	github.com/google/uuid v1.3.0 // indirect
+	github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
+	github.com/googleapis/gax-go/v2 v2.6.0 // indirect
+	github.com/googleapis/go-type-adapters v1.0.0 // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
 	github.com/hashicorp/go-getter v1.5.9 // indirect
@@ -31,7 +37,7 @@ require (
 	github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
 	github.com/hashicorp/go-safetemp v1.0.0 // indirect
 	github.com/hashicorp/go-version v1.3.0 // indirect
-	github.com/hashicorp/hcl/v2 v2.11.1 // indirect
+	github.com/hashicorp/hcl/v2 v2.16.2 // indirect
 	github.com/hashicorp/terraform v1.0.11 // indirect
 	github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
@@ -47,20 +53,21 @@ require (
 	github.com/shopspring/decimal v1.3.1 // indirect
 	github.com/spf13/afero v1.6.0 // indirect
 	github.com/ulikunitz/xz v0.5.8 // indirect
-	github.com/zclconf/go-cty v1.10.0 // indirect
+	github.com/zclconf/go-cty v1.12.1 // indirect
 	go.opencensus.io v0.23.0 // indirect
-	golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect
-	golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
-	golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
-	golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
-	golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect
-	golang.org/x/text v0.3.7 // indirect
-	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
-	google.golang.org/api v0.60.0 // indirect
+	golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect
+	golang.org/x/mod v0.8.0 // indirect
+	golang.org/x/net v0.6.0 // indirect
+	golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
+	golang.org/x/sys v0.5.0 // indirect
+	golang.org/x/text v0.8.0 // indirect
+	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
+	google.golang.org/api v0.102.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
-	google.golang.org/grpc v1.42.0 // indirect
-	google.golang.org/protobuf v1.27.1 // indirect
+	google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e // indirect
+	google.golang.org/grpc v1.50.1 // indirect
+	google.golang.org/protobuf v1.28.1 // indirect
 )
 
+// replace github.com/cycloidio/terracost => /opt/go/src/github.com/cycloidio/terracost
 replace github.com/hashicorp/terraform => github.com/cycloidio/terraform v1.1.9-cy
diff --git a/examples/go.sum b/examples/go.sum
index aafb5cd..0bdbf81 100644
--- a/examples/go.sum
+++ b/examples/go.sum
@@ -25,26 +25,163 @@ cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWc
 cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
 cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
 cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
-cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
 cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
+cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
+cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
+cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
+cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
+cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8=
+cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
+cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=
+cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=
+cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
+cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4=
+cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4=
+cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0=
+cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ=
+cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk=
+cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o=
+cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s=
+cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0=
+cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY=
+cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw=
+cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI=
+cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0=
+cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
 cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA=
+cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY=
+cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s=
+cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM=
+cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI=
+cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY=
+cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI=
+cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
+cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
+cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
+cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
+cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
+cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
+cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
+cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
+cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0=
+cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
+cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=
+cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48=
+cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
+cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I=
+cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4=
+cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0=
+cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs=
+cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc=
+cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM=
+cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ=
+cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo=
+cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE=
+cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I=
+cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ=
+cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo=
+cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo=
+cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ=
+cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4=
+cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0=
+cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8=
+cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU=
+cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU=
+cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y=
+cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg=
+cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk=
+cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w=
+cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk=
+cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg=
+cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM=
+cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA=
+cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o=
+cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A=
+cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0=
+cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0=
+cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc=
+cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc=
+cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
+cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
+cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
+cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8=
+cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08=
+cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4=
+cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w=
+cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE=
+cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM=
+cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY=
+cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s=
+cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=
+cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o=
+cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ=
+cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU=
+cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY=
+cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34=
+cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs=
+cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg=
+cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E=
+cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU=
+cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0=
+cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA=
+cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0=
+cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
 cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
 cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4=
+cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o=
+cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk=
+cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo=
+cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg=
+cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4=
+cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg=
+cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c=
+cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y=
+cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A=
+cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4=
+cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY=
+cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s=
+cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI=
+cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA=
+cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4=
+cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0=
+cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU=
+cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU=
+cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc=
+cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs=
+cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg=
+cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=
+cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
-cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
+cloud.google.com/go/storage v1.23.0 h1:wWRIaDURQA8xxHguFCshYepGlrWIrbBnAmc7wfg07qY=
+cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc=
+cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw=
+cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g=
+cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU=
+cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4=
+cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0=
+cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo=
+cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo=
+cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE=
+cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
+cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
+cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/Azure/azure-sdk-for-go v45.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v47.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
@@ -116,7 +253,6 @@ github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:o
 github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I=
 github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
 github.com/apparentlymart/go-shquot v0.0.1/go.mod h1:lw58XsE5IgUXZ9h0cxnypdx31p9mPFIVEQ9P3c7MlrU=
-github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
 github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
 github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
 github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
@@ -158,6 +294,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
 github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@@ -171,8 +308,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
 github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/cycloidio/sqlr v1.0.0 h1:csN9aZ5PumXr3QswWkoHEzC7+h/2hF5ja/QdcLMEVDQ=
 github.com/cycloidio/sqlr v1.0.0/go.mod h1:s3kP+rzY2ZSdpm+CXpId/OZ3/100q8wnxyxCJLfQRlg=
-github.com/cycloidio/terracost v0.5.0 h1:/2wXJc+pIccA5e7yqBUu5R9+gZb9m2RWbwOwiyeMGrM=
-github.com/cycloidio/terracost v0.5.0/go.mod h1:GPM0OCrhSL3TMnBQrSPQ++RsTyw+yPQoOXcqGLWAJ7M=
 github.com/cycloidio/terraform v1.1.9-cy h1:6IPdzON8v5CSWqCo3qJz2vi4l8Vs7KdCTWZ8RvVj2HM=
 github.com/cycloidio/terraform v1.1.9-cy/go.mod h1:NvfV/Nbb0ffQXcfxoTP1j1FNPS2cTCYE/FBtqRugazI=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -197,6 +332,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
+github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -295,8 +431,11 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
 github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -326,13 +465,26 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
+github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
+github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs=
+github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
-github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=
 github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
+github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
+github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
+github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
+github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=
+github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU=
+github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=
 github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
 github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
+github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=
+github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
 github.com/gophercloud/gophercloud v0.6.1-0.20191122030953-d8ac278c1c9d/go.mod h1:ozGNgr9KYOVATV5jsgHl/ceCDXGuguqOZAzoQ/2vcNM=
 github.com/gophercloud/gophercloud v0.10.1-0.20200424014253-c3bfe50899e5/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
 github.com/gophercloud/utils v0.0.0-20200423144003-7c72efc7435d/go.mod h1:ehWUbLQJPqS0Ep+CxeD559hsm9pthPXadJNKwZkp43w=
@@ -397,13 +549,12 @@ github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04
 github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws=
 github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
 github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
 github.com/hashicorp/hcl/v2 v2.3.0/go.mod h1:d+FwDBbOLvpAM3Z6J7gPj/VoAGkNe/gm352ZhjJ/Zv8=
-github.com/hashicorp/hcl/v2 v2.10.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
-github.com/hashicorp/hcl/v2 v2.11.1 h1:yTyWcXcm9XB0TEkyU/JCRU6rYy4K+mgLtzn2wlrJbcc=
 github.com/hashicorp/hcl/v2 v2.11.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
+github.com/hashicorp/hcl/v2 v2.16.2 h1:mpkHZh/Tv+xet3sy3F9Ld4FyI2tUpWe9x3XtPx9f1a0=
+github.com/hashicorp/hcl/v2 v2.16.2/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng=
 github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d/go.mod h1:Yog5+CPEM3c99L1CL2CFCYoSzgWm5vTU58idbRUaLik=
 github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
 github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
@@ -605,13 +756,18 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
 github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.232/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4=
@@ -636,14 +792,16 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
 github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
 github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
 github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
 github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
 github.com/zclconf/go-cty v1.8.4/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
-github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0=
 github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
+github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY=
+github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA=
 github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
 github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
 go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -683,8 +841,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
-golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0=
+golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -720,9 +878,10 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
 golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -774,10 +933,21 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
 golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -793,9 +963,16 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
 golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
+golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
+golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
+golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
+golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk=
+golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -807,6 +984,10 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -881,11 +1062,28 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc=
 golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -894,8 +1092,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -962,11 +1163,17 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
+golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
+golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
+golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -997,8 +1204,27 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6
 google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
 google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
 google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
-google.golang.org/api v0.60.0 h1:eq/zs5WPH4J9undYM9IP1O7dSr7Yh8Y0GtSCpzGzIUk=
-google.golang.org/api v0.60.0/go.mod h1:d7rl65NZAkEQ90JFzqBjcRq1TVeG5ZoGV3sSpEnnVb4=
+google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
+google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
+google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
+google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
+google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
+google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
+google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
+google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
+google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
+google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
+google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
+google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=
+google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
+google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
+google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
+google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
+google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
+google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
+google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
+google.golang.org/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I=
+google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1049,6 +1275,7 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D
 google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
 google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
 google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
@@ -1066,9 +1293,51 @@ google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEc
 google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
 google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
 google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE=
 google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
+google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
+google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
+google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
+google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
+google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
+google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
+google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=
+google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=
+google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
+google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
+google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
+google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
+google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
+google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
+google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
+google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
+google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
+google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
+google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw=
+google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=
+google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=
+google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U=
+google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
+google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
+google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y=
+google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
 google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -1096,8 +1365,17 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
 google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
 google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
 google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A=
-google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
+google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
+google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
+google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
+google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
+google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -1111,8 +1389,10 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1140,8 +1420,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/examples/terracost.go b/examples/terracost.go
index 7687097..8bc6b86 100644
--- a/examples/terracost.go
+++ b/examples/terracost.go
@@ -15,10 +15,11 @@ import (
 	"github.com/cycloidio/terracost/cost"
 	"github.com/cycloidio/terracost/mysql"
 	"github.com/cycloidio/terracost/terraform"
+	"github.com/cycloidio/terracost/usage"
 	_ "github.com/go-sql-driver/mysql"
 )
 
-func usage() {
+func helpUsage() {
 	fmt.Fprint(os.Stderr, "Terracost\n\n")
 	flag.PrintDefaults()
 	os.Exit(2)
@@ -35,7 +36,7 @@ var (
 
 func main() {
 
-	flag.Usage = usage
+	flag.Usage = helpUsage
 	flag.BoolVar(&flagAWSIngest, "ingest-aws", flagAWSIngest, "Run AWS price ingester")
 	flag.BoolVar(&flagAWSIngestMinimal, "minimal", flagAWSIngestMinimal, "Import the minimum amount of prices")
 	flag.StringVar(&flagAWSIngestRegion, "ingest-aws-region", flagAWSIngestRegion, "AWS region used to ingest")
@@ -51,7 +52,7 @@ func main() {
 	}
 
 	if !flagAWSIngest && flagestimatePlan == "" && flagestimateHCL == "" {
-		usage()
+		helpUsage()
 		os.Exit(0)
 	}
 
@@ -114,7 +115,7 @@ func estimatePlan(path string, backend *mysql.Backend) {
 		os.Exit(1)
 	}
 
-	plan, err := terracost.EstimateTerraformPlan(context.Background(), backend, file)
+	plan, err := terracost.EstimateTerraformPlan(context.Background(), backend, file, usage.Default)
 	if err != nil {
 		fmt.Printf("%s\n", err)
 		os.Exit(1)
@@ -141,7 +142,7 @@ func estimateHCL(path string, provider string, backend *mysql.Backend) {
 	}
 
 	// terraform HCL directory
-	planhcl, err := terracost.EstimateHCL(context.Background(), backend, nil, path, terraformAWSProviderInitializer)
+	planhcl, err := terracost.EstimateHCL(context.Background(), backend, nil, path, usage.Default, terraformAWSProviderInitializer)
 	if err != nil {
 		fmt.Printf("%s\n", err)
 		os.Exit(1)
diff --git a/google/service_string.go b/google/service_string.go
index 8d650c4..5594110 100644
--- a/google/service_string.go
+++ b/google/service_string.go
@@ -44,8 +44,8 @@ func ServiceString(s string) (Service, error) {
 	if val, ok := _ServiceNameToValueMap[s]; ok {
 		return val, nil
 	}
-
-	if val, ok := _ServiceNameToValueMap[strings.ToLower(s)]; ok {
+	s = strings.ToLower(s)
+	if val, ok := _ServiceNameToValueMap[s]; ok {
 		return val, nil
 	}
 	return 0, fmt.Errorf("%s does not belong to Service values", s)
diff --git a/mock/backend.go b/mock/backend.go
index 4252908..4481872 100644
--- a/mock/backend.go
+++ b/mock/backend.go
@@ -12,30 +12,30 @@ import (
 	gomock "github.com/golang/mock/gomock"
 )
 
-// Backend is a mock of Backend interface.
+// Backend is a mock of Backend interface
 type Backend struct {
 	ctrl     *gomock.Controller
 	recorder *BackendMockRecorder
 }
 
-// BackendMockRecorder is the mock recorder for Backend.
+// BackendMockRecorder is the mock recorder for Backend
 type BackendMockRecorder struct {
 	mock *Backend
 }
 
-// NewBackend creates a new mock instance.
+// NewBackend creates a new mock instance
 func NewBackend(ctrl *gomock.Controller) *Backend {
 	mock := &Backend{ctrl: ctrl}
 	mock.recorder = &BackendMockRecorder{mock}
 	return mock
 }
 
-// EXPECT returns an object that allows the caller to indicate expected use.
+// EXPECT returns an object that allows the caller to indicate expected use
 func (m *Backend) EXPECT() *BackendMockRecorder {
 	return m.recorder
 }
 
-// Prices mocks base method.
+// Prices mocks base method
 func (m *Backend) Prices() price.Repository {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Prices")
@@ -43,13 +43,13 @@ func (m *Backend) Prices() price.Repository {
 	return ret0
 }
 
-// Prices indicates an expected call of Prices.
+// Prices indicates an expected call of Prices
 func (mr *BackendMockRecorder) Prices() *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Prices", reflect.TypeOf((*Backend)(nil).Prices))
 }
 
-// Products mocks base method.
+// Products mocks base method
 func (m *Backend) Products() product.Repository {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Products")
@@ -57,7 +57,7 @@ func (m *Backend) Products() product.Repository {
 	return ret0
 }
 
-// Products indicates an expected call of Products.
+// Products indicates an expected call of Products
 func (mr *BackendMockRecorder) Products() *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Products", reflect.TypeOf((*Backend)(nil).Products))
diff --git a/mock/http_client.go b/mock/http_client.go
index 616e9c4..cdd5878 100644
--- a/mock/http_client.go
+++ b/mock/http_client.go
@@ -11,30 +11,30 @@ import (
 	gomock "github.com/golang/mock/gomock"
 )
 
-// HTTPClient is a mock of HTTPClient interface.
+// HTTPClient is a mock of HTTPClient interface
 type HTTPClient struct {
 	ctrl     *gomock.Controller
 	recorder *HTTPClientMockRecorder
 }
 
-// HTTPClientMockRecorder is the mock recorder for HTTPClient.
+// HTTPClientMockRecorder is the mock recorder for HTTPClient
 type HTTPClientMockRecorder struct {
 	mock *HTTPClient
 }
 
-// NewHTTPClient creates a new mock instance.
+// NewHTTPClient creates a new mock instance
 func NewHTTPClient(ctrl *gomock.Controller) *HTTPClient {
 	mock := &HTTPClient{ctrl: ctrl}
 	mock.recorder = &HTTPClientMockRecorder{mock}
 	return mock
 }
 
-// EXPECT returns an object that allows the caller to indicate expected use.
+// EXPECT returns an object that allows the caller to indicate expected use
 func (m *HTTPClient) EXPECT() *HTTPClientMockRecorder {
 	return m.recorder
 }
 
-// Do mocks base method.
+// Do mocks base method
 func (m *HTTPClient) Do(arg0 *http.Request) (*http.Response, error) {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Do", arg0)
@@ -43,7 +43,7 @@ func (m *HTTPClient) Do(arg0 *http.Request) (*http.Response, error) {
 	return ret0, ret1
 }
 
-// Do indicates an expected call of Do.
+// Do indicates an expected call of Do
 func (mr *HTTPClientMockRecorder) Do(arg0 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Do", reflect.TypeOf((*HTTPClient)(nil).Do), arg0)
diff --git a/mock/ingester.go b/mock/ingester.go
index 135ba40..8189a62 100644
--- a/mock/ingester.go
+++ b/mock/ingester.go
@@ -12,30 +12,30 @@ import (
 	gomock "github.com/golang/mock/gomock"
 )
 
-// Ingester is a mock of Ingester interface.
+// Ingester is a mock of Ingester interface
 type Ingester struct {
 	ctrl     *gomock.Controller
 	recorder *IngesterMockRecorder
 }
 
-// IngesterMockRecorder is the mock recorder for Ingester.
+// IngesterMockRecorder is the mock recorder for Ingester
 type IngesterMockRecorder struct {
 	mock *Ingester
 }
 
-// NewIngester creates a new mock instance.
+// NewIngester creates a new mock instance
 func NewIngester(ctrl *gomock.Controller) *Ingester {
 	mock := &Ingester{ctrl: ctrl}
 	mock.recorder = &IngesterMockRecorder{mock}
 	return mock
 }
 
-// EXPECT returns an object that allows the caller to indicate expected use.
+// EXPECT returns an object that allows the caller to indicate expected use
 func (m *Ingester) EXPECT() *IngesterMockRecorder {
 	return m.recorder
 }
 
-// Err mocks base method.
+// Err mocks base method
 func (m *Ingester) Err() error {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Err")
@@ -43,13 +43,13 @@ func (m *Ingester) Err() error {
 	return ret0
 }
 
-// Err indicates an expected call of Err.
+// Err indicates an expected call of Err
 func (mr *IngesterMockRecorder) Err() *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Err", reflect.TypeOf((*Ingester)(nil).Err))
 }
 
-// Ingest mocks base method.
+// Ingest mocks base method
 func (m *Ingester) Ingest(arg0 context.Context, arg1 int) <-chan *price.WithProduct {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Ingest", arg0, arg1)
@@ -57,7 +57,7 @@ func (m *Ingester) Ingest(arg0 context.Context, arg1 int) <-chan *price.WithProd
 	return ret0
 }
 
-// Ingest indicates an expected call of Ingest.
+// Ingest indicates an expected call of Ingest
 func (mr *IngesterMockRecorder) Ingest(arg0, arg1 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ingest", reflect.TypeOf((*Ingester)(nil).Ingest), arg0, arg1)
diff --git a/mock/price_repository.go b/mock/price_repository.go
index e62687f..851dd6d 100644
--- a/mock/price_repository.go
+++ b/mock/price_repository.go
@@ -13,30 +13,30 @@ import (
 	gomock "github.com/golang/mock/gomock"
 )
 
-// PriceRepository is a mock of Repository interface.
+// PriceRepository is a mock of Repository interface
 type PriceRepository struct {
 	ctrl     *gomock.Controller
 	recorder *PriceRepositoryMockRecorder
 }
 
-// PriceRepositoryMockRecorder is the mock recorder for PriceRepository.
+// PriceRepositoryMockRecorder is the mock recorder for PriceRepository
 type PriceRepositoryMockRecorder struct {
 	mock *PriceRepository
 }
 
-// NewPriceRepository creates a new mock instance.
+// NewPriceRepository creates a new mock instance
 func NewPriceRepository(ctrl *gomock.Controller) *PriceRepository {
 	mock := &PriceRepository{ctrl: ctrl}
 	mock.recorder = &PriceRepositoryMockRecorder{mock}
 	return mock
 }
 
-// EXPECT returns an object that allows the caller to indicate expected use.
+// EXPECT returns an object that allows the caller to indicate expected use
 func (m *PriceRepository) EXPECT() *PriceRepositoryMockRecorder {
 	return m.recorder
 }
 
-// DeleteByProductWithKeep mocks base method.
+// DeleteByProductWithKeep mocks base method
 func (m *PriceRepository) DeleteByProductWithKeep(arg0 context.Context, arg1 product.ID, arg2 []price.ID) error {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "DeleteByProductWithKeep", arg0, arg1, arg2)
@@ -44,13 +44,13 @@ func (m *PriceRepository) DeleteByProductWithKeep(arg0 context.Context, arg1 pro
 	return ret0
 }
 
-// DeleteByProductWithKeep indicates an expected call of DeleteByProductWithKeep.
+// DeleteByProductWithKeep indicates an expected call of DeleteByProductWithKeep
 func (mr *PriceRepositoryMockRecorder) DeleteByProductWithKeep(arg0, arg1, arg2 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByProductWithKeep", reflect.TypeOf((*PriceRepository)(nil).DeleteByProductWithKeep), arg0, arg1, arg2)
 }
 
-// Filter mocks base method.
+// Filter mocks base method
 func (m *PriceRepository) Filter(arg0 context.Context, arg1 product.ID, arg2 *price.Filter) ([]*price.Price, error) {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Filter", arg0, arg1, arg2)
@@ -59,13 +59,13 @@ func (m *PriceRepository) Filter(arg0 context.Context, arg1 product.ID, arg2 *pr
 	return ret0, ret1
 }
 
-// Filter indicates an expected call of Filter.
+// Filter indicates an expected call of Filter
 func (mr *PriceRepositoryMockRecorder) Filter(arg0, arg1, arg2 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Filter", reflect.TypeOf((*PriceRepository)(nil).Filter), arg0, arg1, arg2)
 }
 
-// Upsert mocks base method.
+// Upsert mocks base method
 func (m *PriceRepository) Upsert(arg0 context.Context, arg1 *price.WithProduct) (price.ID, error) {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Upsert", arg0, arg1)
@@ -74,7 +74,7 @@ func (m *PriceRepository) Upsert(arg0 context.Context, arg1 *price.WithProduct)
 	return ret0, ret1
 }
 
-// Upsert indicates an expected call of Upsert.
+// Upsert indicates an expected call of Upsert
 func (mr *PriceRepositoryMockRecorder) Upsert(arg0, arg1 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upsert", reflect.TypeOf((*PriceRepository)(nil).Upsert), arg0, arg1)
diff --git a/mock/product_repository.go b/mock/product_repository.go
index 47e67f5..f40b5a8 100644
--- a/mock/product_repository.go
+++ b/mock/product_repository.go
@@ -12,30 +12,30 @@ import (
 	gomock "github.com/golang/mock/gomock"
 )
 
-// ProductRepository is a mock of Repository interface.
+// ProductRepository is a mock of Repository interface
 type ProductRepository struct {
 	ctrl     *gomock.Controller
 	recorder *ProductRepositoryMockRecorder
 }
 
-// ProductRepositoryMockRecorder is the mock recorder for ProductRepository.
+// ProductRepositoryMockRecorder is the mock recorder for ProductRepository
 type ProductRepositoryMockRecorder struct {
 	mock *ProductRepository
 }
 
-// NewProductRepository creates a new mock instance.
+// NewProductRepository creates a new mock instance
 func NewProductRepository(ctrl *gomock.Controller) *ProductRepository {
 	mock := &ProductRepository{ctrl: ctrl}
 	mock.recorder = &ProductRepositoryMockRecorder{mock}
 	return mock
 }
 
-// EXPECT returns an object that allows the caller to indicate expected use.
+// EXPECT returns an object that allows the caller to indicate expected use
 func (m *ProductRepository) EXPECT() *ProductRepositoryMockRecorder {
 	return m.recorder
 }
 
-// Filter mocks base method.
+// Filter mocks base method
 func (m *ProductRepository) Filter(arg0 context.Context, arg1 *product.Filter) ([]*product.Product, error) {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Filter", arg0, arg1)
@@ -44,13 +44,13 @@ func (m *ProductRepository) Filter(arg0 context.Context, arg1 *product.Filter) (
 	return ret0, ret1
 }
 
-// Filter indicates an expected call of Filter.
+// Filter indicates an expected call of Filter
 func (mr *ProductRepositoryMockRecorder) Filter(arg0, arg1 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Filter", reflect.TypeOf((*ProductRepository)(nil).Filter), arg0, arg1)
 }
 
-// FindByVendorAndSKU mocks base method.
+// FindByVendorAndSKU mocks base method
 func (m *ProductRepository) FindByVendorAndSKU(arg0 context.Context, arg1, arg2 string) (*product.Product, error) {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "FindByVendorAndSKU", arg0, arg1, arg2)
@@ -59,13 +59,13 @@ func (m *ProductRepository) FindByVendorAndSKU(arg0 context.Context, arg1, arg2
 	return ret0, ret1
 }
 
-// FindByVendorAndSKU indicates an expected call of FindByVendorAndSKU.
+// FindByVendorAndSKU indicates an expected call of FindByVendorAndSKU
 func (mr *ProductRepositoryMockRecorder) FindByVendorAndSKU(arg0, arg1, arg2 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByVendorAndSKU", reflect.TypeOf((*ProductRepository)(nil).FindByVendorAndSKU), arg0, arg1, arg2)
 }
 
-// Upsert mocks base method.
+// Upsert mocks base method
 func (m *ProductRepository) Upsert(arg0 context.Context, arg1 *product.Product) (product.ID, error) {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Upsert", arg0, arg1)
@@ -74,7 +74,7 @@ func (m *ProductRepository) Upsert(arg0 context.Context, arg1 *product.Product)
 	return ret0, ret1
 }
 
-// Upsert indicates an expected call of Upsert.
+// Upsert indicates an expected call of Upsert
 func (mr *ProductRepositoryMockRecorder) Upsert(arg0, arg1 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upsert", reflect.TypeOf((*ProductRepository)(nil).Upsert), arg0, arg1)
diff --git a/mock/terraform_provider.go b/mock/terraform_provider.go
index d4287d4..0f5ed49 100644
--- a/mock/terraform_provider.go
+++ b/mock/terraform_provider.go
@@ -12,30 +12,30 @@ import (
 	gomock "github.com/golang/mock/gomock"
 )
 
-// TerraformProvider is a mock of Provider interface.
+// TerraformProvider is a mock of Provider interface
 type TerraformProvider struct {
 	ctrl     *gomock.Controller
 	recorder *TerraformProviderMockRecorder
 }
 
-// TerraformProviderMockRecorder is the mock recorder for TerraformProvider.
+// TerraformProviderMockRecorder is the mock recorder for TerraformProvider
 type TerraformProviderMockRecorder struct {
 	mock *TerraformProvider
 }
 
-// NewTerraformProvider creates a new mock instance.
+// NewTerraformProvider creates a new mock instance
 func NewTerraformProvider(ctrl *gomock.Controller) *TerraformProvider {
 	mock := &TerraformProvider{ctrl: ctrl}
 	mock.recorder = &TerraformProviderMockRecorder{mock}
 	return mock
 }
 
-// EXPECT returns an object that allows the caller to indicate expected use.
+// EXPECT returns an object that allows the caller to indicate expected use
 func (m *TerraformProvider) EXPECT() *TerraformProviderMockRecorder {
 	return m.recorder
 }
 
-// Name mocks base method.
+// Name mocks base method
 func (m *TerraformProvider) Name() string {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Name")
@@ -43,13 +43,13 @@ func (m *TerraformProvider) Name() string {
 	return ret0
 }
 
-// Name indicates an expected call of Name.
+// Name indicates an expected call of Name
 func (mr *TerraformProviderMockRecorder) Name() *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*TerraformProvider)(nil).Name))
 }
 
-// ResourceComponents mocks base method.
+// ResourceComponents mocks base method
 func (m *TerraformProvider) ResourceComponents(arg0 map[string]terraform.Resource, arg1 terraform.Resource) []query.Component {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "ResourceComponents", arg0, arg1)
@@ -57,7 +57,7 @@ func (m *TerraformProvider) ResourceComponents(arg0 map[string]terraform.Resourc
 	return ret0
 }
 
-// ResourceComponents indicates an expected call of ResourceComponents.
+// ResourceComponents indicates an expected call of ResourceComponents
 func (mr *TerraformProviderMockRecorder) ResourceComponents(arg0, arg1 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResourceComponents", reflect.TypeOf((*TerraformProvider)(nil).ResourceComponents), arg0, arg1)
diff --git a/usage/usage.go b/usage/usage.go
index 38a9175..0ce1499 100644
--- a/usage/usage.go
+++ b/usage/usage.go
@@ -3,7 +3,7 @@ package usage
 const (
 	// Key is the key used to set the usage
 	// on the values passed to the resources
-	Key string = "usage"
+	Key string = "tc_usage"
 )
 
 // Default is the default Usage that will be used if none is configured


Test patch:
diff --git a/aws/terraform/autoscaling_group_test.go b/aws/terraform/autoscaling_group_test.go
index 9c0971a..10c6706 100644
--- a/aws/terraform/autoscaling_group_test.go
+++ b/aws/terraform/autoscaling_group_test.go
@@ -88,14 +88,14 @@ func TestAutoscalingGroup_Components(t *testing.T) {
 				Name:            "Root volume: Storage",
 				MonthlyQuantity: decimal.NewFromFloat(20),
 				Unit:            "GB",
-				Details:         []string{"gp2"},
+				Details:         []string{"gp3"},
 				ProductFilter: &product.Filter{
 					Provider: util.StringPtr("aws"),
 					Service:  util.StringPtr("AmazonEC2"),
 					Family:   util.StringPtr("Storage"),
 					Location: util.StringPtr("eu-west-1"),
 					AttributeFilters: []*product.AttributeFilter{
-						{Key: "VolumeAPIName", Value: util.StringPtr("gp2")},
+						{Key: "VolumeAPIName", Value: util.StringPtr("gp3")},
 					},
 				},
 			},
@@ -246,14 +246,14 @@ func TestAutoscalingGroup_Components(t *testing.T) {
 				Name:            "Root volume: Storage",
 				MonthlyQuantity: decimal.NewFromFloat(30),
 				Unit:            "GB",
-				Details:         []string{"gp2"},
+				Details:         []string{"gp3"},
 				ProductFilter: &product.Filter{
 					Provider: util.StringPtr("aws"),
 					Service:  util.StringPtr("AmazonEC2"),
 					Family:   util.StringPtr("Storage"),
 					Location: util.StringPtr("eu-west-1"),
 					AttributeFilters: []*product.AttributeFilter{
-						{Key: "VolumeAPIName", Value: util.StringPtr("gp2")},
+						{Key: "VolumeAPIName", Value: util.StringPtr("gp3")},
 					},
 				},
 			},
@@ -291,7 +291,7 @@ func TestAutoscalingGroup_Components(t *testing.T) {
 
 					"root_block_device": []interface{}{
 						map[string]interface{}{
-							"volume_type": "gp2",
+							"volume_type": "gp3",
 							"volume_size": float64(42),
 						},
 					},
@@ -328,14 +328,14 @@ func TestAutoscalingGroup_Components(t *testing.T) {
 				Name:            "Root volume: Storage",
 				MonthlyQuantity: decimal.NewFromFloat(42),
 				Unit:            "GB",
-				Details:         []string{"gp2"},
+				Details:         []string{"gp3"},
 				ProductFilter: &product.Filter{
 					Provider: util.StringPtr("aws"),
 					Service:  util.StringPtr("AmazonEC2"),
 					Family:   util.StringPtr("Storage"),
 					Location: util.StringPtr("eu-west-1"),
 					AttributeFilters: []*product.AttributeFilter{
-						{Key: "VolumeAPIName", Value: util.StringPtr("gp2")},
+						{Key: "VolumeAPIName", Value: util.StringPtr("gp3")},
 					},
 				},
 			},
diff --git a/aws/terraform/efs_file_system_test.go b/aws/terraform/efs_file_system_test.go
new file mode 100644
index 0000000..201f732
--- /dev/null
+++ b/aws/terraform/efs_file_system_test.go
@@ -0,0 +1,163 @@
+package terraform_test
+
+import (
+	"testing"
+
+	"github.com/shopspring/decimal"
+	"github.com/stretchr/testify/require"
+
+	awstf "github.com/cycloidio/terracost/aws/terraform"
+	"github.com/cycloidio/terracost/product"
+	"github.com/cycloidio/terracost/query"
+	"github.com/cycloidio/terracost/terraform"
+	"github.com/cycloidio/terracost/testutil"
+	"github.com/cycloidio/terracost/usage"
+	"github.com/cycloidio/terracost/util"
+)
+
+func TestEFSFileSystem_Components(t *testing.T) {
+	p, err := awstf.NewProvider("aws", "eu-west-1")
+	require.NoError(t, err)
+
+	t.Run("DefaultValues", func(t *testing.T) {
+		tfres := terraform.Resource{
+			Address:      "aws_efs_file_system.test",
+			Type:         "aws_efs_file_system",
+			Name:         "test",
+			ProviderName: "aws",
+			Values:       map[string]interface{}{},
+		}
+		rss := map[string]terraform.Resource{}
+
+		expected := []query.Component{
+			{
+				Name:            "Storage .*-TimedStorage-ByteHrs",
+				MonthlyQuantity: decimal.NewFromFloat(230),
+				Unit:            "GB",
+				Details:         []string{"EFS storage", ".*-TimedStorage-ByteHrs"},
+				Usage:           true,
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEFS"),
+					Family:   util.StringPtr("Storage"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "UsageType", ValueRegex: util.StringPtr(".*-TimedStorage-ByteHrs")},
+					},
+				},
+			},
+		}
+
+		us := usage.Default.GetUsage("aws_efs_file_system")
+		tfres.Values[usage.Key] = us
+		actual := p.ResourceComponents(rss, tfres)
+		testutil.EqualQueryComponents(t, expected, actual)
+	})
+
+	t.Run("WithAllValues", func(t *testing.T) {
+		tfres := terraform.Resource{
+			Address:      "aws_efs_file_system.test",
+			Type:         "aws_efs_file_system",
+			Name:         "test",
+			ProviderName: "aws",
+			Values: map[string]interface{}{
+				"availability_zone": "eu-west-1a",
+				"lifecycle_policy": []interface{}{map[string]interface{}{
+					"transition_to_ia": "AFTER_30_DAYS",
+				}},
+				"throughput_mode":                 "provisioned",
+				"provisioned_throughput_in_mibps": float64(20),
+			},
+		}
+		rss := map[string]terraform.Resource{}
+
+		expected := []query.Component{
+			{
+				Name:            "Storage .*-TimedStorage-ByteHrs",
+				MonthlyQuantity: decimal.NewFromFloat(230),
+				Unit:            "GB",
+				Details:         []string{"EFS storage", ".*-TimedStorage-ByteHrs"},
+				Usage:           true,
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEFS"),
+					Family:   util.StringPtr("Storage"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "UsageType", ValueRegex: util.StringPtr(".*-TimedStorage-ByteHrs")},
+					},
+				},
+			},
+			{
+				Name:            "Provisioned throughput",
+				MonthlyQuantity: decimal.NewFromFloat(8.5),
+				Unit:            "MBps",
+				Details:         []string{"Througput"},
+				Usage:           true,
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEFS"),
+					Family:   util.StringPtr("Provisioned Throughput"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "UsageType", ValueRegex: util.StringPtr("ProvisionedTP-MiBpsHrs")},
+					},
+				},
+			},
+			{
+				Name:            "Storage .*-IATimedStorage-ByteHrs",
+				MonthlyQuantity: decimal.NewFromFloat(100),
+				Unit:            "GB", Details: []string{"EFS storage", ".*-IATimedStorage-ByteHrs"},
+				Usage: true,
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEFS"),
+					Family:   util.StringPtr("Storage"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "UsageType", ValueRegex: util.StringPtr(".*-IATimedStorage-ByteHrs")},
+					},
+				},
+			},
+			{
+				Name:            "Requests Read",
+				MonthlyQuantity: decimal.NewFromFloat(50),
+				Unit:            "GB",
+				Details:         []string{"Requests", "Infrequent Access", "Read"},
+				Usage:           true,
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEFS"),
+					Family:   util.StringPtr("Storage"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "AccessType", Value: util.StringPtr("Read")},
+						{Key: "StorageClass", Value: util.StringPtr("Infrequent Access")},
+					},
+				},
+			},
+			{
+				Name:            "Requests Write",
+				MonthlyQuantity: decimal.NewFromFloat(100),
+				Unit:            "GB",
+				Details:         []string{"Requests", "Infrequent Access", "Write"},
+				Usage:           true,
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEFS"),
+					Family:   util.StringPtr("Storage"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "AccessType", Value: util.StringPtr("Write")},
+						{Key: "StorageClass", Value: util.StringPtr("Infrequent Access")},
+					},
+				},
+			},
+		}
+
+		us := usage.Default.GetUsage("aws_efs_file_system")
+		tfres.Values[usage.Key] = us
+		actual := p.ResourceComponents(rss, tfres)
+		testutil.EqualQueryComponents(t, expected, actual)
+	})
+}
diff --git a/aws/terraform/eks_cluster_test.go b/aws/terraform/eks_cluster_test.go
new file mode 100644
index 0000000..5ed4f39
--- /dev/null
+++ b/aws/terraform/eks_cluster_test.go
@@ -0,0 +1,56 @@
+package terraform
+
+import (
+	"testing"
+
+	"github.com/shopspring/decimal"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	"github.com/cycloidio/terracost/price"
+	"github.com/cycloidio/terracost/product"
+	"github.com/cycloidio/terracost/query"
+	"github.com/cycloidio/terracost/terraform"
+	"github.com/cycloidio/terracost/util"
+)
+
+func TestEKSCluster_Components(t *testing.T) {
+	p, err := NewProvider("aws", "us-east-1")
+	require.NoError(t, err)
+
+	t.Run("EKSCluster", func(t *testing.T) {
+		tfres := terraform.Resource{
+			Address:      "aws_eks_cluster.test",
+			Type:         "aws_eks_cluster",
+			Name:         "test",
+			ProviderName: "aws",
+			Values:       map[string]interface{}{},
+		}
+		rss := map[string]terraform.Resource{}
+
+		expected := []query.Component{
+			{
+				Name:           "EKS Cluster",
+				Details:        []string{"EKSCluster:Compute"},
+				HourlyQuantity: decimal.NewFromInt(1),
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEKS"),
+					Family:   util.StringPtr("Compute"),
+					Location: util.StringPtr("us-east-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "UsageType", Value: util.StringPtr("USE1-AmazonEKS-Hours:perCluster")},
+					},
+				},
+				PriceFilter: &price.Filter{
+					AttributeFilters: []*price.AttributeFilter{
+						{Key: "TermType", Value: util.StringPtr("OnDemand")},
+					},
+				},
+			},
+		}
+
+		actual := p.ResourceComponents(rss, tfres)
+		assert.Equal(t, expected, actual)
+	})
+}
diff --git a/aws/terraform/eks_node_group_test.go b/aws/terraform/eks_node_group_test.go
new file mode 100644
index 0000000..0eabd39
--- /dev/null
+++ b/aws/terraform/eks_node_group_test.go
@@ -0,0 +1,188 @@
+package terraform_test
+
+import (
+	"testing"
+
+	"github.com/shopspring/decimal"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	awstf "github.com/cycloidio/terracost/aws/terraform"
+	"github.com/cycloidio/terracost/price"
+	"github.com/cycloidio/terracost/product"
+	"github.com/cycloidio/terracost/query"
+	"github.com/cycloidio/terracost/terraform"
+	"github.com/cycloidio/terracost/util"
+)
+
+func TestEKSNodeGroup_Components(t *testing.T) {
+	p, err := awstf.NewProvider("aws", "eu-west-1")
+	require.NoError(t, err)
+
+	t.Run("EKSNodeGroupDefault", func(t *testing.T) {
+		tfres := terraform.Resource{
+			Address:      "module.test.aws_eks_node_group.test",
+			Type:         "aws_eks_node_group",
+			Name:         "test",
+			ProviderName: "aws",
+			Values: map[string]interface{}{
+				"scaling_config": []interface{}{map[string]interface{}{
+					"desired_size": 3,
+					"min_size":     2,
+					"max_size":     5,
+				}},
+				"disk_size":      30,
+				"instance_types": []string{"t3.large"},
+			},
+		}
+
+		rss := map[string]terraform.Resource{
+			"aws_launch_template.test": terraform.Resource{
+				Address:      "aws_launch_template.test",
+				Type:         "aws_launch_template",
+				Name:         "test",
+				ProviderName: "aws",
+				Values: map[string]interface{}{
+					"instance_type": "m5.xlarge",
+					"placement":     []interface{}{map[string]interface{}{"availability_zone": "eu-west-1a"}},
+					"block_device_mappings": []interface{}{
+						map[string]interface{}{
+							"device_name": "/dev/sda1",
+							"ebs": []interface{}{
+								map[string]interface{}{"volume_size": float64(30)},
+							},
+						},
+					},
+				},
+			},
+		}
+
+		expected := []query.Component{
+			{
+				Name:           "Compute",
+				HourlyQuantity: decimal.NewFromInt(3),
+				Details:        []string{"Linux", "on-demand", "t3.large"},
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEC2"),
+					Family:   util.StringPtr("Compute Instance"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "CapacityStatus", Value: util.StringPtr("Used")},
+						{Key: "InstanceType", Value: util.StringPtr("t3.large")},
+						{Key: "Tenancy", Value: util.StringPtr("Shared")},
+						{Key: "OperatingSystem", Value: util.StringPtr("Linux")},
+						{Key: "PreInstalledSW", Value: util.StringPtr("NA")},
+					},
+				},
+				PriceFilter: &price.Filter{
+					Unit: util.StringPtr("Hrs"),
+					AttributeFilters: []*price.AttributeFilter{
+						{Key: "TermType", Value: util.StringPtr("OnDemand")},
+					},
+				},
+			},
+			{
+				Name:            "Root volume: Storage",
+				MonthlyQuantity: decimal.NewFromFloat(30),
+				Unit:            "GB",
+				Details:         []string{"gp3"},
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEC2"),
+					Family:   util.StringPtr("Storage"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "VolumeAPIName", Value: util.StringPtr("gp3")},
+					},
+				},
+			},
+		}
+
+		actual := p.ResourceComponents(rss, tfres)
+		assert.Equal(t, expected, actual)
+	})
+
+	t.Run("EKSNodeGroupLaunchTemplate", func(t *testing.T) {
+		tfres := terraform.Resource{
+			Address:      "module.test.aws_eks_node_group.lt",
+			Type:         "aws_eks_node_group",
+			Name:         "lt",
+			ProviderName: "aws",
+			Values: map[string]interface{}{
+				"scaling_config": []interface{}{map[string]interface{}{
+					"desired_size": 2,
+					"min_size":     1,
+					"max_size":     5,
+				}},
+				"launch_template": []interface{}{map[string]interface{}{"id": "aws_launch_template.test"}},
+			},
+		}
+
+		rss := map[string]terraform.Resource{
+			"aws_launch_template.test": terraform.Resource{
+				Address:      "aws_launch_template.test",
+				Type:         "aws_launch_template",
+				Name:         "test",
+				ProviderName: "aws",
+				Values: map[string]interface{}{
+					"instance_type": "m5.xlarge",
+					"placement":     []interface{}{map[string]interface{}{"availability_zone": "eu-west-1a"}},
+					"block_device_mappings": []interface{}{
+						map[string]interface{}{
+							"device_name": "/dev/sda1",
+							"ebs": []interface{}{
+								map[string]interface{}{"volume_size": float64(50)},
+							},
+						},
+					},
+				},
+			},
+		}
+
+		expected := []query.Component{
+			{
+				Name:           "Compute",
+				HourlyQuantity: decimal.NewFromInt(2),
+				Details:        []string{"Linux", "on-demand", "m5.xlarge"},
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEC2"),
+					Family:   util.StringPtr("Compute Instance"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "CapacityStatus", Value: util.StringPtr("Used")},
+						{Key: "InstanceType", Value: util.StringPtr("m5.xlarge")},
+						{Key: "Tenancy", Value: util.StringPtr("Shared")},
+						{Key: "OperatingSystem", Value: util.StringPtr("Linux")},
+						{Key: "PreInstalledSW", Value: util.StringPtr("NA")},
+					},
+				},
+				PriceFilter: &price.Filter{
+					Unit: util.StringPtr("Hrs"),
+					AttributeFilters: []*price.AttributeFilter{
+						{Key: "TermType", Value: util.StringPtr("OnDemand")},
+					},
+				},
+			},
+			{
+				Name:            "Root volume: Storage",
+				MonthlyQuantity: decimal.NewFromFloat(50),
+				Unit:            "GB",
+				Details:         []string{"gp3"},
+				ProductFilter: &product.Filter{
+					Provider: util.StringPtr("aws"),
+					Service:  util.StringPtr("AmazonEC2"),
+					Family:   util.StringPtr("Storage"),
+					Location: util.StringPtr("eu-west-1"),
+					AttributeFilters: []*product.AttributeFilter{
+						{Key: "VolumeAPIName", Value: util.StringPtr("gp3")},
+					},
+				},
+			},
+		}
+
+		actual := p.ResourceComponents(rss, tfres)
+		assert.Equal(t, expected, actual)
+	})
+}
diff --git a/aws/terraform/instance_test.go b/aws/terraform/instance_test.go
index 9219ee8..48717e9 100644
--- a/aws/terraform/instance_test.go
+++ b/aws/terraform/instance_test.go
@@ -61,14 +61,14 @@ func TestInstance_Components(t *testing.T) {
 				Name:            "Root volume: Storage",
 				MonthlyQuantity: decimal.NewFromFloat(8),
 				Unit:            "GB",
-				Details:         []string{"gp2"},
+				Details:         []string{"gp3"},
 				ProductFilter: &product.Filter{
 					Provider: util.StringPtr("aws"),
 					Service:  util.StringPtr("AmazonEC2"),
 					Family:   util.StringPtr("Storage"),
 					Location: util.StringPtr("eu-west-1"),
 					AttributeFilters: []*product.AttributeFilter{
-						{Key: "VolumeAPIName", Value: util.StringPtr("gp2")},
+						{Key: "VolumeAPIName", Value: util.StringPtr("gp3")},
 					},
 				},
 			},
diff --git a/aws/terraform/volume_test.go b/aws/terraform/volume_test.go
index 99e9136..4110742 100644
--- a/aws/terraform/volume_test.go
+++ b/aws/terraform/volume_test.go
@@ -35,14 +35,14 @@ func TestVolume_Components(t *testing.T) {
 				Name:            "Storage",
 				MonthlyQuantity: decimal.NewFromFloat(42),
 				Unit:            "GB",
-				Details:         []string{"gp2"},
+				Details:         []string{"gp3"},
 				ProductFilter: &product.Filter{
 					Provider: util.StringPtr("aws"),
 					Service:  util.StringPtr("AmazonEC2"),
 					Family:   util.StringPtr("Storage"),
 					Location: util.StringPtr("eu-west-1"),
 					AttributeFilters: []*product.AttributeFilter{
-						{Key: "VolumeAPIName", Value: util.StringPtr("gp2")},
+						{Key: "VolumeAPIName", Value: util.StringPtr("gp3")},
 					},
 				},
 			},
diff --git a/e2e/aws_estimation_test.go b/e2e/aws_estimation_test.go
index 09a6a2b..f66067a 100644
--- a/e2e/aws_estimation_test.go
+++ b/e2e/aws_estimation_test.go
@@ -227,7 +227,7 @@ func TestAWSEstimation(t *testing.T) {
 
 			pcost, err = plan.PlannedCost()
 			assert.NoError(t, err)
-			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(31.984), "USD"), pcost)
+			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(31.544), "USD"), pcost)
 
 			diffs := plan.ResourceDifferences()
 			require.Len(t, diffs, 1)
@@ -247,7 +247,7 @@ func TestAWSEstimation(t *testing.T) {
 
 			pcost, err = plan.PlannedCost()
 			assert.NoError(t, err)
-			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(31.984), "USD"), pcost)
+			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(31.544), "USD"), pcost)
 
 			diffs := plan.ResourceDifferences()
 			require.Len(t, diffs, 1)
@@ -296,7 +296,7 @@ func TestAWSEstimation(t *testing.T) {
 
 			pcost, err := plan.PlannedCost()
 			assert.NoError(t, err)
-			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(62.892), "USD"), pcost)
+			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(62.716), "USD"), pcost)
 		})
 		t.Run("SuccessMagento", func(t *testing.T) {
 
@@ -318,7 +318,18 @@ func TestAWSEstimation(t *testing.T) {
 
 			pcost, err := plan.PlannedCost()
 			assert.NoError(t, err)
-			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(691.863), "USD"), pcost)
+			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(690.983), "USD"), pcost)
+		})
+		t.Run("SuccessEKS", func(t *testing.T) {
+
+			plan, err := costestimation.EstimateHCL(ctx, backend, nil, "../testdata/aws/stack-eks", usage.Default)
+			require.NoError(t, err)
+
+			assert.Nil(t, plan.Prior)
+
+			pcost, err := plan.PlannedCost()
+			assert.NoError(t, err)
+			assertCostEqual(t, cost.NewMonthly(decimal.NewFromFloat(99.798), "USD"), pcost)
 		})
 		t.Run("SuccessRemote", func(t *testing.T) {
 
diff --git a/terraform/hcl_test.go b/terraform/hcl_test.go
index 95b190d..93f5451 100644
--- a/terraform/hcl_test.go
+++ b/terraform/hcl_test.go
@@ -39,7 +39,7 @@ func TestExtractQueriesFromHCL(t *testing.T) {
 						"ami":           "some-ami",
 						"instance_type": "t2.micro",
 						"provider":      ".aws",
-						"usage": map[string]interface{}{
+						"tc_usage": map[string]interface{}{
 							"usage": "set_instance",
 						},
 					}, res.Values)
@@ -58,7 +58,7 @@ func TestExtractQueriesFromHCL(t *testing.T) {
 								"volume_type":           "gp2",
 							},
 						},
-						"usage": map[string]interface{}{
+						"tc_usage": map[string]interface{}{
 							"usage": "set_instance",
 						},
 					}, res.Values)
@@ -76,7 +76,7 @@ func TestExtractQueriesFromHCL(t *testing.T) {
 								"lb_protocol":       "tcp",
 							},
 						},
-						"usage": map[string]interface{}{
+						"tc_usage": map[string]interface{}{
 							"usage": "set_elb",
 						},
 					}, res.Values)
@@ -85,9 +85,9 @@ func TestExtractQueriesFromHCL(t *testing.T) {
 					assert.Equal(t, "aws_ebs_volume", res.Type)
 					assert.Equal(t, "volume", res.Name)
 					assert.Equal(t, map[string]interface{}{
-						"size":  float64(20),
-						"type":  "gp2",
-						"usage": map[string]interface{}(nil),
+						"size":     float64(20),
+						"type":     "gp2",
+						"tc_usage": map[string]interface{}(nil),
 					}, res.Values)
 
 				case "module.rds.aws_db_instance.db":
@@ -99,7 +99,7 @@ func TestExtractQueriesFromHCL(t *testing.T) {
 						"instance_class":    "db.t3.small",
 						"multi_az":          true,
 						"storage_type":      "gp2",
-						"usage":             map[string]interface{}(nil),
+						"tc_usage":          map[string]interface{}(nil),
 					}, res.Values)
 
 				default:
diff --git a/testdata/aws/stack-eks/module-eks/main.tf b/testdata/aws/stack-eks/module-eks/main.tf
new file mode 100644
index 0000000..8ed1101
--- /dev/null
+++ b/testdata/aws/stack-eks/module-eks/main.tf
@@ -0,0 +1,15 @@
+resource "aws_eks_cluster" "example" {
+  name     = "example"
+  role_arn = aws_iam_role.example.arn
+
+  vpc_config {
+    subnet_ids = [aws_subnet.example1.id, aws_subnet.example2.id]
+  }
+
+  # Ensure that IAM Role permissions are created before and deleted after EKS Cluster handling.
+  # Otherwise, EKS will not be able to properly delete EKS managed EC2 infrastructure such as Security Groups.
+  depends_on = [
+    aws_iam_role_policy_attachment.example-AmazonEKSClusterPolicy,
+    aws_iam_role_policy_attachment.example-AmazonEKSVPCResourceController,
+  ]
+}
diff --git a/testdata/aws/stack-eks/module-eks/node.tf b/testdata/aws/stack-eks/module-eks/node.tf
new file mode 100644
index 0000000..c0d8d07
--- /dev/null
+++ b/testdata/aws/stack-eks/module-eks/node.tf
@@ -0,0 +1,40 @@
+resource "aws_launch_template" "foo" {
+  name = "foo"
+
+  block_device_mappings {
+    device_name = "/dev/sdf"
+
+    ebs {
+      volume_size = 200
+    }
+  }
+
+  ebs_optimized = true
+
+  instance_type = "t2.micro"
+}
+
+resource "aws_eks_node_group" "example" {
+  cluster_name    = aws_eks_cluster.example.name
+  node_group_name = "example"
+  node_role_arn   = aws_iam_role.example.arn
+  subnet_ids      = aws_subnet.example[*].id
+
+  scaling_config {
+    desired_size = 1
+    max_size     = 2
+    min_size     = 1
+  }
+
+  instance_types = ["t3.large"]
+
+  launch_template {
+    id = aws_launch_template.foo.id
+  }
+  update_config {
+    max_unavailable = 1
+  }
+}
+
+
+
diff --git a/testdata/aws/stack-eks/provider.tf b/testdata/aws/stack-eks/provider.tf
new file mode 100644
index 0000000..a2f84ad
--- /dev/null
+++ b/testdata/aws/stack-eks/provider.tf
@@ -0,0 +1,19 @@
+terraform {
+  required_providers {
+    aws = {
+      source  = "hashicorp/aws"
+      version = "~> 4.0"
+    }
+  }
+}
+
+# Configure the AWS Provider
+provider "aws" {
+  region = "eu-west-1"
+}
+
+
+module "eks" {
+  source = "./module-eks"
+
+}
diff --git a/testutil/equal_query_components.go b/testutil/equal_query_components.go
new file mode 100644
index 0000000..dcb0500
--- /dev/null
+++ b/testutil/equal_query_components.go
@@ -0,0 +1,25 @@
+package testutil
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/cycloidio/terracost/query"
+	"github.com/stretchr/testify/assert"
+)
+
+// EqualQueryComponents will compare the components but the MonthlyQuantity will be
+// compared via String and the rest with assert.Equal
+func EqualQueryComponents(t *testing.T, eqcs, aqcs []query.Component) {
+	t.Helper()
+
+	for i, eqc := range eqcs {
+		if eqc.MonthlyQuantity.String() == aqcs[i].MonthlyQuantity.String() {
+			eqc.MonthlyQuantity = aqcs[i].MonthlyQuantity
+		} else {
+			assert.Fail(t, fmt.Sprintf("Expected MonthlyQuantity to be %q but was %q", eqc.MonthlyQuantity.String(), aqcs[i].MonthlyQuantity.String()))
+			continue
+		}
+		assert.Equal(t, eqc, aqcs[i])
+	}
+}