-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement data aws_pricing_product #5057
Conversation
1711f4d
to
68d64c1
Compare
Hi @julienduchesne, thanks for submitting this data source! I did want to touch base briefly about the below:
We are just starting the process of writing up Terraform provider development best practices documentation and this is likely an item that would appear there. 😄 At first blush, this seems like it belongs in its own separate data source and most likely in its own provider, rather than something to implement piecemeal per resource and data source everywhere. For example, from an operator perspective, this might be useful (calling the new provider data "aws_pricing_product" "example" {
service_code = "AmazonRedshift"
filters = [
{
field = "instanceType"
value = "ds1.xlarge"
},
{
field = "location"
value = "US East (N. Virginia)"
},
]
}
data "json_query" "example" {
json = "${data.aws_pricing_product.example.json}"
query = "terms.OnDemand.*.priceDimensions.*.pricePerUnit.USD"
}
output "example" {
values = "${data.json_query.example.value}"
} I cannot guarantee that HashiCorp would necessarily be willing to maintain this as a new provider, but if it makes sense from a generic sense, I can reach out and gather opinions on hosting it as a community provider as part of the Terraform Provider Development Program. There is also an existing community provider implementation that might be able to help here: https://github.com/EvilSuperstars/terraform-provider-jsondecode Better news though is that while the Terraform 0.12 preview blog post did not specifically mention it, Terraform 0.12 will be able to support a data "aws_pricing_product" "example" {
service_code = "AmazonRedshift"
filters = [
{
field = "instanceType"
value = "ds1.xlarge"
},
{
field = "location"
value = "US East (N. Virginia)"
},
]
}
# Potential Terraform 0.12 syntax - may change during implementation
# Also, not sure about the exact attribute reference architecture myself :)
output "example" {
values = jsondecode(data.json_query.example.value).terms.OnDemand.*.priceDimensions.*.pricePerUnit.USD
} That feature can be tracked upstream at: hashicorp/terraform#10363 With all that said, we likely would not want to merge in the extra dependency or |
88667be
to
d403191
Compare
Alright, here you go make testacc TESTARGS='-run=TestAccDataSourceAwsPricingProduct'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./... -v -run=TestAccDataSourceAwsPricingProduct -timeout 120m
? github.com/terraform-providers/terraform-provider-aws [no test files]
=== RUN TestAccDataSourceAwsPricingProduct_ec2
--- PASS: TestAccDataSourceAwsPricingProduct_ec2 (14.45s)
=== RUN TestAccDataSourceAwsPricingProduct_redshift
--- PASS: TestAccDataSourceAwsPricingProduct_redshift (14.05s)
PASS
ok github.com/terraform-providers/terraform-provider-aws/aws 28.508s Let me know if anything else is not OK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking pretty good 👍 A few minor things below and this should be ready to ship.
package aws | ||
|
||
import ( | ||
"log" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpick: The Go imports seem to be a little off formatting wise. The stdlib imports should be grouped and alphabetically sorted at the top, a blank line, then external imports grouped and alphabetically sorted.
We tend to prefer using goimports
for managing these consistently (and automatically) everywhere 👍
) | ||
|
||
const ( | ||
awsPricingTermMatch = "TERM_MATCH" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should prefer to use the available SDK constant: pricing.FilterTypeTermMatch
return fmt.Errorf("Error reading pricing of products: %s", err) | ||
} | ||
|
||
if err = verifyProductsPriceListLength(resp.PriceList); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpick: given this function is not being used elsewhere and not explicitly unit tested, we can remove the indirection and just include the logic inline here.
) | ||
|
||
func TestAccDataSourceAwsPricingProduct_ec2(t *testing.T) { | ||
os.Setenv("AWS_DEFAULT_REGION", "us-east-1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should save the original value and reset it after completion or this could break other tests:
oldRegion := os.Getenv("AWS_DEFAULT_REGION")
os.Setenv("AWS_DEFAULT_REGION", "us-east-1")
defer os.Setenv("AWS_DEFAULT_REGION", oldRegion)
The same should be applied to the other acceptance test. Admittedly, we need to remove using environment variables for this purpose. 🙁
## Argument Reference | ||
|
||
* `service_code` - (Required) The code of the service. Available service codes can be fetched using the DescribeServices pricing API call. | ||
* `filters` - (Required) A list of filters. Passed directly to the API (see GetProducts API reference). These filters must describe a single product, this resource will fail if more than one product is returned by the API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to describe the filters
nested fields as well, e.g.
### filters
* `field` (Required) The attribute name that you want to filter on.
* `value` (Required) The attribute value that you want to filter on.
--- | ||
layout: "aws" | ||
page_title: "AWS: aws_pricing_product" | ||
sidebar_current: "docs-aws-datasource-pricing-product" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This page needs a sidebar link added to website/aws.erb
22a621c
to
1d729c1
Compare
Looks great, @julienduchesne! 🚀
|
This has been released in version 1.26.0 of the AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. |
I couldn't quite get the pre 0.12 proposed syntax working. The following seems to work okay though: variable "instance_type" {}
provider "aws" {
alias = "us-east-1"
region = "us-east-1"
}
data "aws_region" "current" {}
data "aws_pricing_product" "example" {
provider = aws.us-east-1
service_code = "AmazonEC2"
filters {
field = "capacitystatus"
value = "Used"
}
filters {
field = "instanceType"
value = var.instance_type
}
filters {
field = "operatingSystem"
value = "Linux"
}
filters {
field = "location"
value = data.aws_region.current.description
}
filters {
field = "preInstalledSw"
value = "NA"
}
filters {
field = "licenseModel"
value = "No License required"
}
filters {
field = "tenancy"
value = "Shared"
}
}
output "on_demand_price" {
value = tonumber(values(values(jsondecode(data.aws_pricing_product.example.result).terms.OnDemand)[0].priceDimensions)[0].pricePerUnit.USD)
} Not sure if there's a better/cleaner way to be getting at the relevant data though? Would it be worth adding this as an example to the resource's documentation? |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks! |
Fixes #5009
Changes proposed in this pull request:
Output from acceptance testing: