Skip to content

Commit

Permalink
Merge pull request #4511 from saravanan30erd/issue-4449
Browse files Browse the repository at this point in the history
issue #4449 Fix the issue using Arn field instead of Name in IamInstanceProfileSpecification
  • Loading branch information
bflad authored May 11, 2018
2 parents 742554f + ad5673f commit b8c9017
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 12 deletions.
15 changes: 15 additions & 0 deletions aws/resource_aws_spot_fleet_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ func resourceAwsSpotFleetRequest() *schema.Resource {
ForceNew: true,
Optional: true,
},
"iam_instance_profile_arn": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
},
"ami": {
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -378,6 +383,12 @@ func buildSpotFleetLaunchSpecification(d map[string]interface{}, meta interface{
}
}

if v, ok := d["iam_instance_profile_arn"]; ok {
opts.IamInstanceProfile = &ec2.IamInstanceProfileSpecification{
Arn: aws.String(v.(string)),
}
}

if v, ok := d["user_data"]; ok {
opts.UserData = aws.String(base64Encode([]byte(v.(string))))
}
Expand Down Expand Up @@ -944,6 +955,10 @@ func launchSpecToMap(l *ec2.SpotFleetLaunchSpecification, rootDevName *string) m
m["iam_instance_profile"] = aws.StringValue(l.IamInstanceProfile.Name)
}

if l.IamInstanceProfile != nil && l.IamInstanceProfile.Arn != nil {
m["iam_instance_profile_arn"] = aws.StringValue(l.IamInstanceProfile.Arn)
}

if l.UserData != nil {
m["user_data"] = userDataHashSum(aws.StringValue(l.UserData))
}
Expand Down
167 changes: 167 additions & 0 deletions aws/resource_aws_spot_fleet_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"log"
"regexp"
"testing"
"time"

Expand Down Expand Up @@ -107,6 +108,30 @@ func TestAccAWSSpotFleetRequest_instanceInterruptionBehavior(t *testing.T) {
})
}

func TestAccAWSSpotFleetRequest_iamInstanceProfileArn(t *testing.T) {
var sfr ec2.SpotFleetRequestConfig
rName := acctest.RandString(10)
rInt := acctest.RandInt()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSpotFleetRequestConfigIamInstanceProfileArn(rName, rInt),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSSpotFleetRequestExists(
"aws_spot_fleet_request.foo", &sfr),
resource.TestCheckResourceAttr(
"aws_spot_fleet_request.foo", "spot_request_state", "active"),
testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn(&sfr),
),
},
},
})
}

func TestAccAWSSpotFleetRequest_changePriceForcesNewRequest(t *testing.T) {
var before, after ec2.SpotFleetRequestConfig
rName := acctest.RandString(10)
Expand Down Expand Up @@ -627,6 +652,29 @@ func TestAccAWSSpotFleetRequest_WithELBs(t *testing.T) {
})
}

func testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn(
sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc {
return func(s *terraform.State) error {
if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 {
return errors.New("Missing launch specification")
}

spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0]

profile := spec.IamInstanceProfile
if profile == nil {
return fmt.Errorf("Expected IamInstanceProfile to be set, got nil")
}
//Validate the string whether it is ARN
re := regexp.MustCompile("arn:aws:iam::\\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*")
if !re.MatchString(*profile.Arn) {
return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn)
}

return nil
}
}

func TestAccAWSSpotFleetRequest_WithTargetGroups(t *testing.T) {
var sfr ec2.SpotFleetRequestConfig
rName := acctest.RandString(10)
Expand Down Expand Up @@ -782,6 +830,125 @@ resource "aws_spot_fleet_request" "foo" {
`, rName, rInt, rInt, rName)
}

func testAccAWSSpotFleetRequestConfigIamInstanceProfileArn(rName string, rInt int) string {
return fmt.Sprintf(`
resource "aws_key_pair" "debugging" {
key_name = "tmp-key-%s"
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com"
}
resource "aws_iam_policy" "test-policy" {
name = "test-policy-%d"
path = "/"
description = "Spot Fleet Request ACCTest Policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"ec2:DescribeImages",
"ec2:DescribeSubnets",
"ec2:RequestSpotInstances",
"ec2:TerminateInstances",
"ec2:DescribeInstanceStatus",
"iam:PassRole"
],
"Resource": ["*"]
}]
}
EOF
}
resource "aws_iam_policy_attachment" "test-attach" {
name = "test-attachment-%d"
roles = ["${aws_iam_role.test-role.name}"]
policy_arn = "${aws_iam_policy.test-policy.arn}"
}
resource "aws_iam_role" "test-role" {
name = "test-role-%s"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": [
"spotfleet.amazonaws.com",
"ec2.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role" "test-role1" {
name = "tf-test-role1-%s"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": [
"spotfleet.amazonaws.com",
"ec2.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "test-role-policy1" {
name = "tf-test-role-policy1-%s"
role = "${aws_iam_role.test-role1.name}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
}
EOF
}
resource "aws_iam_instance_profile" "test-iam-instance-profile1" {
name = "tf-test-profile1-%s"
role = "${aws_iam_role.test-role1.name}"
}
resource "aws_spot_fleet_request" "foo" {
iam_fleet_role = "${aws_iam_role.test-role.arn}"
spot_price = "0.005"
target_capacity = 2
valid_until = "2019-11-04T20:44:20Z"
terminate_instances_with_expiration = true
instance_interruption_behaviour = "stop"
wait_for_fulfillment = true
launch_specification {
instance_type = "m1.small"
ami = "ami-516b9131"
key_name = "${aws_key_pair.debugging.key_name}"
iam_instance_profile_arn = "${aws_iam_instance_profile.test-iam-instance-profile1.arn}"
}
depends_on = ["aws_iam_policy_attachment.test-attach"]
}
`, rName, rInt, rInt, rName, rName, rName, rName)
}

func testAccAWSSpotFleetRequestConfigChangeSpotBidPrice(rName string, rInt int) string {
return fmt.Sprintf(`
resource "aws_key_pair" "debugging" {
Expand Down
27 changes: 15 additions & 12 deletions website/docs/r/spot_fleet_request.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@ resource "aws_spot_fleet_request" "cheap_compute" {
valid_until = "2019-11-04T20:44:20Z"
launch_specification {
instance_type = "m4.10xlarge"
ami = "ami-1234"
spot_price = "2.793"
placement_tenancy = "dedicated"
instance_type = "m4.10xlarge"
ami = "ami-1234"
spot_price = "2.793"
placement_tenancy = "dedicated"
iam_instance_profile_arn = "${aws_iam_instance_profile.example.arn}"
}
launch_specification {
instance_type = "m4.4xlarge"
ami = "ami-5678"
key_name = "my-key"
spot_price = "1.117"
availability_zone = "us-west-1a"
subnet_id = "subnet-1234"
weighted_capacity = 35
instance_type = "m4.4xlarge"
ami = "ami-5678"
key_name = "my-key"
spot_price = "1.117"
iam_instance_profile_arn = "${aws_iam_instance_profile.example.arn}"
availability_zone = "us-west-1a"
subnet_id = "subnet-1234"
weighted_capacity = 35
root_block_device {
volume_size = "300"
Expand Down Expand Up @@ -95,7 +97,8 @@ across different markets and instance types.
**Note:** This takes in similar but not
identical inputs as [`aws_instance`](instance.html). There are limitations on
what you can specify. See the list of officially supported inputs in the
[reference documentation](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_SpotFleetLaunchSpecification.html). Any normal [`aws_instance`](instance.html) parameter that corresponds to those inputs may be used.
[reference documentation](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_SpotFleetLaunchSpecification.html). Any normal [`aws_instance`](instance.html) parameter that corresponds to those inputs may be used and it have
a additional parameter `iam_instance_profile_arn` takes `aws_iam_instance_profile` attribute `arn` as input.

* `spot_price` - (Optional; Default: On-demand price) The maximum bid price per unit hour.
* `wait_for_fulfillment` - (Optional; Default: false) If set, Terraform will
Expand Down

0 comments on commit b8c9017

Please sign in to comment.