-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
d/aws_ec2_instance_spot_price - add new data source #12504
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
21919ad
d/aws_ec2_instance_spot_price - add new data source
p0pr0ck5 6a7a60b
remove accidental inclusion of local test example
p0pr0ck5 37ad45d
make instance_type and availability_zone optional
p0pr0ck5 613c130
simplify DescribeSpotPriceHistory usage
p0pr0ck5 e354ef2
copypasta
p0pr0ck5 4d1e0bd
add more thorough tests for aws_ec2_instance_spot_price resource
p0pr0ck5 14ab44c
use dynamic data sources for filtering in tests
p0pr0ck5 be0353b
format spot_price_timestamp as RFC3339
p0pr0ck5 df35b6f
rebase aws/provider.go
p0pr0ck5 ce454d9
fix up tests
p0pr0ck5 00be40d
lint and typo fixes
p0pr0ck5 495c8e7
update docs
p0pr0ck5 3d92b6f
whitespace
p0pr0ck5 2e91549
aws_ec2_instance_spot_price -> aws_ec2_spot_price
p0pr0ck5 f1ff164
support spot price data by solely filtering
p0pr0ck5 4a5163a
update documentation following resource rename
p0pr0ck5 5a167da
copypasta documention updates
p0pr0ck5 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
) | ||
|
||
func dataSourceAwsEc2SpotPrice() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceAwsEc2SpotPriceRead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"filter": dataSourceFiltersSchema(), | ||
"instance_type": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"availability_zone": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"spot_price": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"spot_price_timestamp": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceAwsEc2SpotPriceRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).ec2conn | ||
|
||
now := time.Now() | ||
input := &ec2.DescribeSpotPriceHistoryInput{ | ||
StartTime: &now, | ||
} | ||
|
||
if v, ok := d.GetOk("instance_type"); ok { | ||
instanceType := v.(string) | ||
input.InstanceTypes = []*string{ | ||
aws.String(instanceType), | ||
} | ||
} | ||
|
||
if v, ok := d.GetOk("availability_zone"); ok { | ||
availabilityZone := v.(string) | ||
input.AvailabilityZone = aws.String(availabilityZone) | ||
} | ||
|
||
if v, ok := d.GetOk("filter"); ok { | ||
input.Filters = buildAwsDataSourceFilters(v.(*schema.Set)) | ||
} | ||
|
||
var foundSpotPrice []*ec2.SpotPrice | ||
|
||
err := conn.DescribeSpotPriceHistoryPages(input, func(output *ec2.DescribeSpotPriceHistoryOutput, lastPage bool) bool { | ||
foundSpotPrice = append(foundSpotPrice, output.SpotPriceHistory...) | ||
return true | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("error reading EC2 Spot Price History: %w", err) | ||
} | ||
|
||
if len(foundSpotPrice) == 0 { | ||
return fmt.Errorf("no EC2 Spot Price History found matching criteria; try different search") | ||
} | ||
|
||
if len(foundSpotPrice) > 1 { | ||
return fmt.Errorf("multiple EC2 Spot Price History results found matching criteria; try different search") | ||
} | ||
|
||
resultSpotPrice := foundSpotPrice[0] | ||
|
||
d.Set("spot_price", resultSpotPrice.SpotPrice) | ||
d.Set("spot_price_timestamp", (*resultSpotPrice.Timestamp).Format(time.RFC3339)) | ||
d.SetId(resource.UniqueId()) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
) | ||
|
||
func TestAccAwsEc2SpotPriceDataSource(t *testing.T) { | ||
dataSourceName := "data.aws_ec2_spot_price.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAwsEc2SpotPrice(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: nil, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAwsEc2SpotPriceDataSourceConfig(), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestMatchResourceAttr(dataSourceName, "spot_price", regexp.MustCompile(`^\d+\.\d+$`)), | ||
resource.TestMatchResourceAttr(dataSourceName, "spot_price_timestamp", regexp.MustCompile(rfc3339RegexPattern)), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAwsEc2SpotPriceDataSourceFilter(t *testing.T) { | ||
dataSourceName := "data.aws_ec2_spot_price.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAwsEc2SpotPrice(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: nil, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAwsEc2SpotPriceDataSourceFilterConfig(), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestMatchResourceAttr(dataSourceName, "spot_price", regexp.MustCompile(`^\d+\.\d+$`)), | ||
resource.TestMatchResourceAttr(dataSourceName, "spot_price_timestamp", regexp.MustCompile(rfc3339RegexPattern)), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccPreCheckAwsEc2SpotPrice(t *testing.T) { | ||
conn := testAccProvider.Meta().(*AWSClient).ec2conn | ||
|
||
input := &ec2.DescribeSpotPriceHistoryInput{ | ||
MaxResults: aws.Int64(5), | ||
} | ||
|
||
_, err := conn.DescribeSpotPriceHistory(input) | ||
|
||
if testAccPreCheckSkipError(err) { | ||
t.Skipf("skipping acceptance testing: %s", err) | ||
} | ||
|
||
if err != nil { | ||
t.Fatalf("unexpected PreCheck error: %s", err) | ||
} | ||
} | ||
|
||
func testAccAwsEc2SpotPriceDataSourceConfig() string { | ||
return fmt.Sprintf(` | ||
data "aws_region" "current" {} | ||
|
||
data "aws_ec2_instance_type_offering" "test" { | ||
filter { | ||
name = "instance-type" | ||
values = ["m5.xlarge"] | ||
} | ||
} | ||
|
||
data "aws_availability_zones" "available" { | ||
state = "available" | ||
|
||
filter { | ||
name = "region-name" | ||
values = [data.aws_region.current.name] | ||
} | ||
} | ||
|
||
data "aws_ec2_spot_price" "test" { | ||
instance_type = data.aws_ec2_instance_type_offering.test.instance_type | ||
|
||
availability_zone = data.aws_availability_zones.available.names[0] | ||
|
||
filter { | ||
name = "product-description" | ||
values = ["Linux/UNIX"] | ||
} | ||
} | ||
`) | ||
} | ||
|
||
func testAccAwsEc2SpotPriceDataSourceFilterConfig() string { | ||
return fmt.Sprintf(` | ||
data "aws_region" "current" {} | ||
|
||
data "aws_ec2_instance_type_offering" "test" { | ||
filter { | ||
name = "instance-type" | ||
values = ["m5.xlarge"] | ||
} | ||
} | ||
|
||
data "aws_availability_zones" "available" { | ||
state = "available" | ||
|
||
filter { | ||
name = "region-name" | ||
values = [data.aws_region.current.name] | ||
} | ||
} | ||
|
||
data "aws_ec2_spot_price" "test" { | ||
filter { | ||
name = "product-description" | ||
values = ["Linux/UNIX"] | ||
} | ||
|
||
filter { | ||
name = "instance-type" | ||
values = [data.aws_ec2_instance_type_offering.test.instance_type] | ||
} | ||
|
||
filter { | ||
name = "availability-zone" | ||
values = [data.aws_availability_zones.available.names[0]] | ||
} | ||
} | ||
`) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
subcategory: "EC2" | ||
layout: "aws" | ||
page_title: "AWS: aws_ec2_instance_spot_price" | ||
description: |- | ||
Information about most recent Spot Price for a given EC2 instance. | ||
--- | ||
|
||
# Data Source: aws_ec2_instance_spot_price | ||
|
||
Information about most recent Spot Price for a given EC2 instance. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
data "aws_ec2_instance_spot_price" "example" { | ||
instance_type = "t3.medium" | ||
availability_zone = "us-west-2a" | ||
|
||
filter { | ||
name = "product-description" | ||
values = ["Linux/UNIX"] | ||
} | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `instance_type` - (Optional) The type of instance for which to query Spot Price information. | ||
* `availability_zone` - (Optional) The availability zone in which to query Spot price information. | ||
* `filter` - (Optional) One or more configuration blocks containing name-values filters. See the [EC2 API Reference](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSpotPriceHistory.html) for supported filters. Detailed below. | ||
|
||
### filter Argument Reference | ||
|
||
* `name` - (Required) Name of the filter. | ||
* `values` - (Required) List of one or more values for the filter. | ||
|
||
## Attribute Reference | ||
|
||
In addition to all arguments above, the following attributes are exported: | ||
|
||
* `spot_price` - The most recent Spot Price value for the given instance type and AZ. | ||
* `spot_price_timestamp` - The timestamp at which the Spot Price value was published. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
@p0pr0ck5 @bflad This data source is documented as
aws_ec2_instance_spot_price
(noteinstance
) but as this line demonstrates, the name is actuallyaws_ec2_spot_price
. So either the docs or the data source name here has to be changed.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.
Please see: #14680