GithubHelp home page GithubHelp logo

cycloidio / terracost Goto Github PK

View Code? Open in Web Editor NEW
281.0 7.0 30.0 15.06 MB

Cloud cost estimation for Terraform in your CLI

License: MIT License

Go 99.54% Makefile 0.46%
cost-estimation cost-optimization cost-management terraform terraform-cost-estimation infrastructure-as-code aws cloud gcp azure

terracost's Introduction

TerraCost logo

TerraCost

PkgGoDev

Go library for estimating Terraform costs using ingested cloud vendor prices. It is meant to be imported and used by programs (API's or standalone) with access to a MySQL-compatible database and the Internet.

Installation

go mod edit -replace github.com/hashicorp/terraform=github.com/cycloidio/[email protected] && go get github.com/cycloidio/terracost

We need to do a -replace because of golang/go#30354 (comment). We have a custom fork of Terraform and in order to use TerraCost it needs to be replaced when importing also.

Requirements

  • Go 1.16 or newer
  • MySQL database

Provider support

Currently Terracost supports the following providers and with an specific subset of resources from them:

Google Credentials

To be able to ingest the pricing data from Google the credentials needed have to have access to Compute Engine API and have also billing enabled. This is needed to be able to fetch the Machine Types, for the SKUs we would only need an normal set of credentials (or even API Key) but as we need both we have to use the more complex one. If you do not know how to activate those permissions, just use the credentials and the import will fail and on the logs will inform of what is missing and how to activate it.

Usage

Migrating the database

db, err := sql.Open("mysql", "root:password@tcp(IP:3306)/databasename?multiStatements=true")

// Can be called on every start of your program, it does nothing if the migrations
// have been executed already.
err = mysql.Migrate(context.Background(), db, "pricing_migrations")

Ingesting pricing data

db, err := sql.Open("mysql", "root:password@tcp(IP:3306)/databasename?multiStatements=true")
backend := mysql.NewBackend(db)

// service can be "AmazonEC2" or "AmazonRDS"
// region is any AWS region, e.g. "us-east-1" or "eu-west-3"
ingester, err := aws.NewIngester(service, region)
err = terracost.IngestPricing(context.Background(), backend, ingester)

Tracking ingestion progress

We're using the github.com/machinebox/progress library for tracking ingestion progress.

  1. Create a channel that will receive progress updates and set up a goroutine (it will print the bytes ingested out of bytes total and remaining time each time progress update is sent on the channel):
progressCh := make(chan progress.Progress, 0)

go func() {
	for p := range progressCh {
		// Check the docs for all available methods: https://pkg.go.dev/github.com/machinebox/progress#Progress
		fmt.Printf("%d / %d (%s remaining)\n", p.N(), p.Size(), p.Remaining().String())
	}
}()
  1. Initialize an ingester capable of tracking progress (in this example the channel will receive an update every 5 seconds):
ingester, err := aws.NewIngester(service, region, aws.WithProgress(progressCh, 5*time.Second))
  1. Use the ingester as in the previous section.

Estimating a Terraform plan

Plan estimation is possible after all the relevant pricing data have been ingested and stored in the database.

  1. Generate a plan using terraform and convert it to JSON:
terraform plan -out update.tfplan
terraform show -json update.tfplan > tfplan.json
  1. Read the plan file, estimate it and show the resource differences:
db, err := db.Open("mysql", "...")
backend := mysql.NewBackend(db)

file, err := os.Open("path/to/tfplan.json")
plan, err := terracost.EstimateTerraformPlan(context.Background(), backend, file)

for _, res := range plan.ResourceDifferences() {
  priorCost, err := res.PriorCost()
  plannedCost, err := res.PlannedCost()

  fmt.Printf("%s: %s -> %s\n", res.Address, priorCost, plannedCost)
}

Check the documentation for all available fields.

Usage estimation

Some resources do cannot be estimated just by the configuration and need some extra usage information, for that we have some default on usage/usage.go which are also all the resources and options we support currently and can be overwritten when estimating if passing a custom one instead of the custom Default one.

Examples

For more examples, please check examples.

Contributing

For Contributing Guide, please read CONTIBUTING.md.

License

This project is licensed under the MIT license. Please see LICENSE for more details.

Meet Cycloid

Cycloid is a hybrid cloud DevOps collaboration platform providing end-to-end frameworks to accelerate and industrialize software delivery.

As of now, we have three open-source tools:

  • TerraCognita: Read from your existing cloud providers and generate IaC in Terraform
  • InfraMap: Reads .tfstate or HCL to generate a graph specific for each provider
  • TerraCost: Cloud cost estimation for Terraform in the CLI

...and the functionality of each is also embedded in our DevOps solution, which you can find out more about here.

terracost's People

Contributors

chammach avatar folago avatar talset avatar theskch avatar xescugc avatar xlr-8 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

terracost's Issues

Support GCP resources

Planned

  • google_compute_disk
  • google_compute_instance
  • google_sql_database_instance
  • google_redis_instance
  • google_memcache_instance
  • google_container_cluster
  • google_container_node_pool
  • google_compute_forwarding_rule
  • google_compute_global_forwarding_rule

Changelog + Versioning

IMO it starts to be worth it to add a CHANGELOG and use Versioning even if it's manually tagging for now.

Estimation: try to set default values to ease estimation

In case where the HCL are modules, it might happen that not all variables are specified. It would be interesting to see if we can set those variables with some default values to highlight how much it got estimated by default. So instance type, counts, etc could be defaulted to certain value.

I'm not sure how do-able that is, but still seems interesting to take a look as Terraform knows both the name, type and potential values associated with it.

Add usage cost

Some resources do not have specific attributes that would be used to calculate the price, this price is set when the resource is used. For this we'll allow a specific file that would specify that usage for the specific resources so we can make a estimation on their usage instead of having a 0 cost.

The format of this file for now will be:

resource_type_default_usage:
    aws_lambda_function:
      monthly_requests: 100000 # Monthly requests to the Lambda function.
      request_duration_ms: 500 # Average duration of each request in milliseconds.

Improve installation documentation

It's not clear that you first need to clone the project and cd into it before running the go get mentioned here.

I wanted to install it, and after reading the docs, I simply copy-pasted the given command, and got the following error:

$ go mod edit -replace github.com/hashicorp/terraform=github.com/cycloidio/[email protected] && go get github.com/cycloidio/terracost
go: go.mod file not found in current directory or any parent directory; see 'go help modules'

Then I figured out I may need to clone the repo first and cd into it, which did the trick.

(Also, I know it's a bit the cherry on top of the cake, but providing a brew formula would be awesome for macOS users ๐Ÿ˜…)

Support Azure resources

Planned

  • azurerm_firewall
  • azurerm_linux_virtual_machine
  • azurerm_linux_virtual_machine_scale_set
  • azurerm_managed_disk
  • azurerm_mariadb_server
  • azurerm_mssql_elasticpool
  • azurerm_mysql_server
  • azurerm_postgresql_server
  • azurerm_sql_database
  • azurerm_virtual_machine
  • azurerm_virtual_machine_scale_set
  • azurerm_windows_virtual_machine
  • azurerm_windows_virtual_machine_scale_set

Keep historical prices

Old prices should be marked as "historical" instead of being replaced by the newly ingested prices. This way it'll be possible to retrieve historical prices at any time in the past, see the historical price evolution, or inform/notify users when/why a price changes.

Add documentation for library consumers

  • Improve and point to https://pkg.go.dev/ (once open-sourced)
  • Document AWS-specific info and current limitations:
    • EC2: only on-demand Linux instances with no pre-installed software are supported (e.g. no spot, reserved, Windows, SQL Server, etc.)
    • EC2: only the Compute and Storage costs are calculated (e.g. no GPU, monitoring, etc.)
    • document all the defaults and assumptions that are used in the calculations (e.g. for EC2: 730 hours in a month, for EBS: the "gp2" type, 8 GB storage, etc.) - this should include links to the appropriate provider docs
  • README and "how to contribute" guide
  • Add "how does it work" section, explaining the way the library interacts with the DB and the way cost is estimated

estimation: Return a list of errors instead of failing the entire process

Abstract

Failing the entire cost estimation process because of a single failure in retrieving the correct product/price is not the best UX. The failure should be recorded and an error returned, however, all the successful estimates should be returned as well.

Implementation details

For example, by adding a new field to the cost.State struct that holds the failed resources and the error of each, e.g. in a map[string]error. As well as a method on cost.Plan that can be used to retrieve all the failed resources.

Suggestions/ideas

This is similar in concept to #12 and could probably be accomplished together.

aws: Improve ingestion time

Abstract

Currently, the ingestion of AWS products is performed strictly sequentially and there's a lot of room for optimization. Making the process parallel should drastically decrease the time it takes to ingest AWS pricing data.

Implementation details

TBD

Suggestions/ideas

TBD

aws: optional "minimal" ingestion mode

Abstract

One of the ways we can improve AWS ingestion time (#13) is to support a "minimal" mode. In this mode, only a subset of all the data would be ingested, correlating to the resources we support. This will let library users save time and space by ingesting only around 10% (in the case of EC2) of the pricing file.

Implementation details

This can be done by having a new AWS ingestion option, e.g. WithIngestionFilter, that would accept a filtering function. The function would be called for each pricing record, marking the items that should (and shouldn't) be ingested. Terracost might then define two such functions out-of-the-box: a DefaultFilter that ingests everything and a MinimalFilter that only ingests records necessary for the library to work.

The "minimal" mode shouldn't be the default, as it will require re-ingestion each time new resources or attributes of already existing resources become supported.

estimation: Return a list of skipped resources

Abstract

Currently, only the resources that had been successfully estimated are returned. The user has no way of knowing which resources from the plan were skipped (due to e.g. not being supported).

The skipped resources should be returned alongside the estimated ones.

Implementation details

This could be accomplished by including a SkippedResources []string field (or similar) in the cost.State struct, as well as having a helper method on the cost.Plan to extract them.

Suggestions/ideas

Many Terraform resources are inherently free (such as from the null or local providers) and shouldn't be included as "skipped." One idea could be to have a list of free resources that should never be estimated and that should never be marked as "skipped." The other would be to ignore all unknown providers and mark as skipped only unsupported resources of supported providers.

Introduce a linter and setup CI

We need a linter to check the correctness and style of the codebase. This, together with tests, should be run automatically for every PR and every merge to master. Possibly, this pipeline could also build and publish a release.

Accept anonymized Terraform plan

Abstract

While Terracost was designed with an assumption that the cost estimation backend is a fully trusted environment, this might not always be the case. The plan file may contain private and confidential data that the user should not send over network, especially to an untrusted backend.

Suggestions/ideas

The library needs to accept anonymized cost keys, that can be extracted from a Terraform plan (or tfstate) locally. The extraction could be performed using a third-party tool, though a function and command line utility should also be provided by Terracost.

The cost keys should only contain data about the resources that is absolutely necessary to perform the estimation. All other data must be stripped from the plan.

Implementation details

  • implement a function and command line utility to extract anonymized cost keys from a Terraform plan
  • accept the cost keys, in addition to the tfplan format, for cost estimation

estimation: add support for provider names from Terraform 0.13+

Terraform changed the way the providerName is used in the plan file. This will break the plans generated by Terraform 0.13+ that use full URI's as provider name. For example, "aws" was replaced by "registry.terraform.io/hashicorp/aws" and as such it's not easily linkable to the provider name from the configuration block (that stays as "aws").

terraform: support for child modules

According to the Terraform JSON output format any module (including the root module) may contain child modules that describe their own resources. The module tree is described recursively.

Currently, no module other than the root module will be estimated as the child_modules property is ignored by the Terraform plan reader.

mysql: change aws testdata from eu-west-3 to us-east-1

Should we switch from eu-west-3 to us-east-1
Most of the services are available on us-east-1 first and few services might not be on eu-west-3 yet.

If yes we will have to re-generate the testdata SQL and fix the unittest

Enable estimating cost from terraform references

As of now, the estimate only works when the resources variables are set directly and not via reference.
The goal of this issue is to find a way to enable this behavior and allow to estimate resources that have variables set via reference to other resources or data.

aws: expose a list of supported services (regions?)

Abstract

In order to be able to use the aws.Ingester type correctly, the user needs to know the name of the service they want to ingest. This is not always obvious - for example, AmazonEC2 is used and not just the expected EC2. The users of the library should be able to retrieve a list of all supported services so that it can be displayed or manipulated in any other way.

Implementation details

A function in the aws package that returns a []string containing a list of all supported AWS services that can be ingested.

Suggestions/ideas

This list can also be used internally to validate the requested service, before issuing a request to AWS.

Support AWS resources

Done

  • aws_db_instance
  • aws_ebs_volume
  • aws_instance
  • aws_elb
  • aws_lb / aws_alb

Currently in progress

  • aws_ebs_snapshot
  • aws_ebs_snapshot_copy
  • aws_rds_cluster
  • aws_rds_cluster_instance

Planned

  • aws_autoscaling_group
  • aws_cloudhsm_v2_hsm
  • aws_cloudwatch_dashboard
  • aws_cloudwatch_metric_alarm
  • aws_dynamodb_table
  • aws_ecs_service
  • aws_elasticache_cluster
  • aws_elasticsearch_domain
  • aws_kms_key
  • aws_lambda_function
  • aws_nat_gateway

Readme: Add some output examples

Tiny suggestion for the Readme file:
It would be nice to have an example of what kind of output the project is capable of, something like a few lines with resources and costs (could even be a screenshot).

This way people stumbling upon the project/readme can understand better what they can expect to do with terracost.

Support Terraform provider aliases

Abstract

Currently, only the Terraform provider without an alias will work. Since in the case of AWS, the only way to define resources in multiple regions is to use provider aliases (with each provider config referencing a different region), this is needed in order to be able to estimate resources in multiple regions.

Implementation details

The provider_name property from both planned_values and prior_state blocks reference the full name of a provider (e.g. registry.terraform.io/hashicorp/aws). From that point, there is no way of retrieving the actual provider config or even its alias. The only way is to cross-reference the configuration block - there the alias will be available under the provider_config_key property (e.g. "aws.alias")

interpolate variable with non-module HCL files

Currently, variable interpolation works when the Terraform code is structured as module (like here

But the estimation will fail with a simple TF file such:

provider "aws" {
  region = "eu-west-1"
}

variable "front_ebs_optimized" {
  default = false
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "m3.xlarge"

  ebs_optimized = var.front_ebs_optimized
}

Because the variable is not replaced by the real value

expected

Implement the variable interpolation on non-module terraform code

Improve end-to-end testing

In order to make the testing simpler and more reliable these are the general ideas on how to improve it:

  • include a MySQL Docker container and a docker-compose
  • add a Makefile that starts the DB container before running the tests
  • ingest real pricing data to use it for the tests (?)
  • include a real Terraform project, using terraform containers to generate the plan for each of the supported Terraform versions

Plan variables are forced to be `string`

For some reason we forced the plan.variables to have the value of type string, this was causing errors like

Error: unable to estimate terraform plan file: unable to estimate cost insfrastructure: [ Unexpected message from the external service Cost Estimation: json: cannot unmarshal object into Go struct field Variable.variables.value of type string]

Error: unable to estimate terraform plan file: unable to estimate cost insfrastructure: [ Unexpected message from the external service Cost Estimation: json: cannot unmarshal bool into Go struct field Variable.variables.value of type string]

We'll fix this by changing the type to interface{} and casting it to string when we need to.

Reduce the unsupported resources output

Right now we return all the resources we do not support as unsupported but we should reduce that list to only resources that can have some kind of pricing so then the list would be more precise.

estimation: referencing region with a variable in provider config doesn't work

Currently, the terraform package expects the region to be defined directly (using "constant_value") and variables are not supported. However, specifying the region with a variable is a common use case and must be supported, e.g.:

variable "region" {
  type = string
  default = "eu-west-1"
}

provider "aws" {
  region = var.region
}

Adding Open Telekom Cloud (OTC) as a new Provider

Hi cycloidio Team and terracost friends,

I would like to add the Open Telekom Cloud as a new Provider. There is an public available price API, so getting the prices should not be a problem. According to the contribution file, it is necessary to discuss some things here. I would also be happy to get a bit of guidance, if the idea of adding OTC is accepted.

Maybe some side facts about the OTC: It is an european, OpenStack based public cloud, of course with an already existent terraform provider. The public regions are in germany and netherlands and there is a third region in switzerland for the swiss market. The main focus is data protection and sovereignty

Resources billed per hour should use `hours` as unit

On the JSON generated by Terracost, some resources like aws_instance are not correctly computed.
The cost result is correct, but there's a miss on quantity and unit attributes:

{
   "planned_cost":"121.336",
   "planned_hourly_cost":"0.166214",
   "prior_cost":"0",
   "prior_hourly_cost":"0",
   "resource_estimates":[
      {
         "address":"module.nexus.aws_instance.nexus",
         "components":[
            {
               "label":"Compute",
               "planned":{
                  "cost":"119.136",
                  "details":[
                     "Linux",
                     "on-demand",
                     "t3a.xlarge"
                  ],
                  "hourly_cost":"0.1632",
                  "quantity":1
               },
               "rate":"119.136"
            },
            {
               "label":"Root volume: Storage",
               "planned":{
                  "cost":"2.2",
                  "details":[
                     "gp2"
                  ],
                  "hourly_cost":"0.003014",
                  "quantity":20
               },
               "rate":"0.11",
               "unit":"GB"
            }
         ],
         "planned_cost":"121.336",
         "planned_hourly_cost":"0.166214",
         "prior_cost":"0",
         "prior_hourly_cost":"0",
         "provider":"aws",
         "type":"aws_instance"
      }
   ],
}

On this example, the rate, quantity and unit should be calculated in terms of hours, using 730 as quantity instead of considering 1 instance as a quantity. Users are not buying an instance, but an amount of hour of an instance.

Unable to Install TerraCost on Mac on zsh

Hello,

The command provided to install Terracost is deprecated

Provided Instruction:

go get github.com/cycloidio/terracost

Error:

go: go.mod file not found in current directory or any parent directory.
        'go get' is no longer supported outside a module.
        To build and install a command, use 'go install' with a version,
        like 'go install example.com/cmd@latest'
        For more information, see https://golang.org/doc/go-get-install-deprecation
        or run 'go help get' or 'go help install'.

I, therefore, tried the new command.

go install github.com/cycloidio/terracost 
go: 'go install' requires a version when the current directory is not in a module
Try 'go install github.com/cycloidio/terracost@latest' to install the latest version

As you see, even that did not work, so tried the recommended command. It still gives me an error.

go install github.com/cycloidio/terracost@latest
go: github.com/cycloidio/terracost@latest (in github.com/cycloidio/[email protected]):
        The go.mod file for the module providing named packages contains one or
        more replace directives. It must not contain directives that would cause
        it to be interpreted differently than if it were the main module.

Add support for Terragrunt format

We'll basically run Terragrunt and run TerraCost on the generated modules.

The output is still TBD, I'm thinking on changing the EstimateHCL return from cost.Plan to []cost.Plan as at the end each one should have a different separated estimation. The other is to have the cost.Plan differentiate between the different possible modules and define the Prior, Planned *cost.State for each one of them this way the main signature does not change that much. The cost.State will not change as it's the minimal set of attributes.

Automatically fetch AWS regions

Instead of hardcoding a map of AWS region codes and their names, we should consider to instead fetch them directly from AWS. There are at least two different options of dealing with this:

  1. Having a go generate target that fetches the regions and generates a file based on them,
  2. Whenever starting the ingester, fetching the regions live from AWS

Considering how infrequently the list changes, option 1 might be less obtrusive.

See: https://github.com/cycloidio/poc/pull/11#discussion_r498819645

Expose `provider` and `type` for estimated resources

The cost.Resource and cost.ResourceDiff structs are missing any information about which provider they belong to and which type they are. Currently, the only way to extract this is from the address, however, this is being complicated by the fact that module resource addresses are different from root module ones and also by the effort that library consumers would require.

These two fields would be much better provided by us on the aforementioned types.

Return detailed prices per resource

In order to have a better idea of what is changing, we would like to have a detailed resource list.

We need to have it (at least, but could be interesting to have an ASCII table output) as a JSON oneliner.

The goal would be to expose for each resource: the price per hour, the price per month (to figure what will be the bill), and the delta change (if there's a change between runs).

From a structure point of view, here is a proposal:

{
  "aws_instance": [
    { "hourly_cost": "xx$", "monthly_cost": "xx$", "monthly_delta": "xx$"},
    ...
  ],
  ...
}

This structure would allow to group resources by type also.

Simplify usage (e.g. by adding API, CLI)

Abstract

Currently, this project can only be used as a library that is imported into an existing Go program. This heavily limits the ease of use and adoption. While having it be used as a library is our main use case, we should allow for other methods as well.

Implementation details

The proposal is to add a few flexible building blocks that the users could use (or not) depending on needs:

  1. An HTTP handler that estimates the costs of a TF plan that can be easily added into any Go server
  2. A simple API whose entire purpose would be to expose the handler above, allowing the users to start the API and not have to write a single line of code
  3. CLI that is able to send requests to the HTTP handler above (either included in the simple API or any other Go server), parse the cost estimation result and print it out

These three components should be able to cover most use cases.

Cannot install terracost with go 1.18

Steps to Reproduce:

  • Using go version: go version go1.18.1 darwin/arm64
    • Run: go install github.com/cycloidio/terracost@latest:

    • Install fails with error message:

      go: github.com/cycloidio/terracost@latest (in github.com/cycloidio/[email protected]):
      	The go.mod file for the module providing named packages contains one or
      	more replace directives. It must not contain directives that would cause
      	it to be interpreted differently than if it were the main module.
      

go.mod file contains:

replace github.com/hashicorp/terraform => github.com/hashicorp/terraform v0.15.3

Expected result:

Installation of terracost should work on Go >= 1.16

GO111MODULE=off Workaround fails on missing hashicorp/terraform/configs:

  • Force using GOPATH install behavior with:
    • export GO111MODULE=off; go get github.com/cycloidio/terracost

    • Returns error message:

      cannot find package "github.com/hashicorp/terraform/configs" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/github.com/hashicorp/terraform/configs (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/github.com/hashicorp/terraform/configs (from $GOPATH)
      
  • Similar issues when trying to forcibly install terraform + dependencies to GOPATH via go get:
    • export GO111MODULE=off; go get

    • Returns more errors:

      export GO111MODULE=off;  go get github.com/hashicorp/terraform
      cannot find package "github.com/vmihailenco/msgpack/v4" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/github.com/vmihailenco/msgpack/v4 (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/github.com/vmihailenco/msgpack/v4 (from $GOPATH)
      cannot find package "github.com/vmihailenco/msgpack/v4/codes" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/github.com/vmihailenco/msgpack/v4/codes (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/github.com/vmihailenco/msgpack/v4/codes (from $GOPATH)
      cannot find package "go.etcd.io/etcd/clientv3" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/go.etcd.io/etcd/clientv3 (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/go.etcd.io/etcd/clientv3 (from $GOPATH)
      cannot find package "go.etcd.io/etcd/clientv3/concurrency" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/go.etcd.io/etcd/clientv3/concurrency (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/go.etcd.io/etcd/clientv3/concurrency (from $GOPATH)
      cannot find package "go.etcd.io/etcd/pkg/transport" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/go.etcd.io/etcd/pkg/transport (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/go.etcd.io/etcd/pkg/transport (from $GOPATH)
      cannot find package "github.com/hashicorp/hcl/hcl/ast" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/github.com/hashicorp/hcl/hcl/ast (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/github.com/hashicorp/hcl/hcl/ast (from $GOPATH)
      cannot find package "github.com/hashicorp/hcl/hcl/parser" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/github.com/hashicorp/hcl/hcl/parser (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/github.com/hashicorp/hcl/hcl/parser (from $GOPATH)
      cannot find package "github.com/hashicorp/hcl/hcl/token" in any of:
        /opt/homebrew/Cellar/go/1.18.1/libexec/src/github.com/hashicorp/hcl/hcl/token (from $GOROOT)
        /Users/exampleuser/src/pub/go/src/github.com/hashicorp/hcl/hcl/token (from $GOPATH)
      

Support Terraform state files (tfstate)

The TFState files contain all of the information we need to perform cost estimation. There's no reason why we shouldn't be able to load it into a cost.State.

To do this, we could add a new function in the terraform package to ExtractQueriesFromStatefile (or similar) that would return []query.Resource. These would be then used in the same way as currently for the plans.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.