Merge pull request #3940 from hashicorp/b-aws-spot-instance-updates
providers/aws: Update Spot Instance request to provide connection information
This commit is contained in:
commit
7772a66b2f
|
@ -97,6 +97,14 @@ func resourceAwsSpotInstanceRequestCreate(d *schema.ResourceData, meta interface
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the instance is configured with a Network Interface (a subnet, has
|
||||||
|
// public IP, etc), then the instanceOpts.SecurityGroupIds and SubnetId will
|
||||||
|
// be nil
|
||||||
|
if len(instanceOpts.NetworkInterfaces) > 0 {
|
||||||
|
spotOpts.LaunchSpecification.SecurityGroupIds = instanceOpts.NetworkInterfaces[0].Groups
|
||||||
|
spotOpts.LaunchSpecification.SubnetId = instanceOpts.NetworkInterfaces[0].SubnetId
|
||||||
|
}
|
||||||
|
|
||||||
// Make the spot instance request
|
// Make the spot instance request
|
||||||
log.Printf("[DEBUG] Requesting spot bid opts: %s", spotOpts)
|
log.Printf("[DEBUG] Requesting spot bid opts: %s", spotOpts)
|
||||||
resp, err := conn.RequestSpotInstances(spotOpts)
|
resp, err := conn.RequestSpotInstances(spotOpts)
|
||||||
|
@ -172,6 +180,10 @@ func resourceAwsSpotInstanceRequestRead(d *schema.ResourceData, meta interface{}
|
||||||
// Instance ID is not set if the request is still pending
|
// Instance ID is not set if the request is still pending
|
||||||
if request.InstanceId != nil {
|
if request.InstanceId != nil {
|
||||||
d.Set("spot_instance_id", *request.InstanceId)
|
d.Set("spot_instance_id", *request.InstanceId)
|
||||||
|
// Read the instance data, setting up connection information
|
||||||
|
if err := readInstance(d, meta); err != nil {
|
||||||
|
return fmt.Errorf("[ERR] Error reading Spot Instance Data: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
d.Set("spot_request_state", *request.State)
|
d.Set("spot_request_state", *request.State)
|
||||||
d.Set("tags", tagsToMap(request.Tags))
|
d.Set("tags", tagsToMap(request.Tags))
|
||||||
|
@ -179,6 +191,54 @@ func resourceAwsSpotInstanceRequestRead(d *schema.ResourceData, meta interface{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readInstance(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{
|
||||||
|
InstanceIds: []*string{aws.String(d.Get("spot_instance_id").(string))},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// If the instance was not found, return nil so that we can show
|
||||||
|
// that the instance is gone.
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" {
|
||||||
|
return fmt.Errorf("no instance found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some other error, report it
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If nothing was found, then return no state
|
||||||
|
if len(resp.Reservations) == 0 {
|
||||||
|
return fmt.Errorf("no instances found")
|
||||||
|
}
|
||||||
|
|
||||||
|
instance := resp.Reservations[0].Instances[0]
|
||||||
|
|
||||||
|
// Set these fields for connection information
|
||||||
|
if instance != nil {
|
||||||
|
d.Set("public_dns", instance.PublicDnsName)
|
||||||
|
d.Set("public_ip", instance.PublicIpAddress)
|
||||||
|
d.Set("private_dns", instance.PrivateDnsName)
|
||||||
|
d.Set("private_ip", instance.PrivateIpAddress)
|
||||||
|
|
||||||
|
// set connection information
|
||||||
|
if instance.PublicIpAddress != nil {
|
||||||
|
d.SetConnInfo(map[string]string{
|
||||||
|
"type": "ssh",
|
||||||
|
"host": *instance.PublicIpAddress,
|
||||||
|
})
|
||||||
|
} else if instance.PrivateIpAddress != nil {
|
||||||
|
d.SetConnInfo(map[string]string{
|
||||||
|
"type": "ssh",
|
||||||
|
"host": *instance.PrivateIpAddress,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func resourceAwsSpotInstanceRequestUpdate(d *schema.ResourceData, meta interface{}) error {
|
func resourceAwsSpotInstanceRequestUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
conn := meta.(*AWSClient).ec2conn
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,26 @@ func TestAccAWSSpotInstanceRequest_vpc(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSSpotInstanceRequest_SubnetAndSG(t *testing.T) {
|
||||||
|
var sir ec2.SpotInstanceRequest
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSSpotInstanceRequestDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSSpotInstanceRequestConfig_SubnetAndSG,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSSpotInstanceRequestExists(
|
||||||
|
"aws_spot_instance_request.foo", &sir),
|
||||||
|
testAccCheckAWSSpotInstanceRequest_InstanceAttributes(&sir),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testCheckKeyPair(keyName string, sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
|
func testCheckKeyPair(keyName string, sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
|
||||||
return func(*terraform.State) error {
|
return func(*terraform.State) error {
|
||||||
if sir.LaunchSpecification.KeyName == nil {
|
if sir.LaunchSpecification.KeyName == nil {
|
||||||
|
@ -178,6 +198,44 @@ func testAccCheckAWSSpotInstanceRequestAttributes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSSpotInstanceRequest_InstanceAttributes(
|
||||||
|
sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
||||||
|
resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{
|
||||||
|
InstanceIds: []*string{sir.InstanceId},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" {
|
||||||
|
return fmt.Errorf("Spot Instance not found")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If nothing was found, then return no state
|
||||||
|
if len(resp.Reservations) == 0 {
|
||||||
|
return fmt.Errorf("Spot Instance not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
instance := resp.Reservations[0].Instances[0]
|
||||||
|
|
||||||
|
var sgMatch bool
|
||||||
|
for _, s := range instance.SecurityGroups {
|
||||||
|
// Hardcoded name for the security group that should be added inside the
|
||||||
|
// VPC
|
||||||
|
if *s.GroupName == "tf_test_sg_ssh" {
|
||||||
|
sgMatch = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !sgMatch {
|
||||||
|
return fmt.Errorf("Error in matching Spot Instance Security Group, expected 'tf_test_sg_ssh', got %s", instance.SecurityGroups)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckAWSSpotInstanceRequestAttributesVPC(
|
func testAccCheckAWSSpotInstanceRequestAttributesVPC(
|
||||||
sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
|
sir *ec2.SpotInstanceRequest) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
@ -249,3 +307,44 @@ resource "aws_spot_instance_request" "foo_VPC" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const testAccAWSSpotInstanceRequestConfig_SubnetAndSG = `
|
||||||
|
resource "aws_spot_instance_request" "foo" {
|
||||||
|
ami = "ami-6f6d635f"
|
||||||
|
spot_price = "0.05"
|
||||||
|
instance_type = "t1.micro"
|
||||||
|
wait_for_fulfillment = true
|
||||||
|
subnet_id = "${aws_subnet.tf_test_subnet.id}"
|
||||||
|
vpc_security_group_ids = ["${aws_security_group.tf_test_sg_ssh.id}"]
|
||||||
|
associate_public_ip_address = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_vpc" "default" {
|
||||||
|
cidr_block = "10.0.0.0/16"
|
||||||
|
enable_dns_hostnames = true
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf_test_vpc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "tf_test_subnet" {
|
||||||
|
vpc_id = "${aws_vpc.default.id}"
|
||||||
|
cidr_block = "10.0.0.0/24"
|
||||||
|
map_public_ip_on_launch = true
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf_test_subnet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_security_group" "tf_test_sg_ssh" {
|
||||||
|
name = "tf_test_sg_ssh"
|
||||||
|
description = "tf_test_sg_ssh"
|
||||||
|
vpc_id = "${aws_vpc.default.id}"
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "tf_test_sg_ssh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
Loading…
Reference in New Issue