Skip to content
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

provider/aws: Add support for ENI as Instance Primary Network Interface #12694

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions builtin/providers/aws/resource_aws_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,11 @@ func resourceAwsInstance() *schema.Resource {
},

"network_interface_id": {
Type: schema.TypeString,
Computed: true,
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"vpc_security_group_ids", "subnet_id", "associate_public_ip_address"},
},

"public_ip": {
Expand Down Expand Up @@ -1260,7 +1263,13 @@ func buildAwsInstanceOpts(
}
}

if hasSubnet && associatePublicIPAddress {
if v, ok := d.GetOk("network_interface_id"); ok {
ni := &ec2.InstanceNetworkInterfaceSpecification{
DeviceIndex: aws.Int64(int64(0)),
NetworkInterfaceId: aws.String(v.(string)),
}
opts.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{ni}
} else if hasSubnet && associatePublicIPAddress {
// If we have a non-default VPC / Subnet specified, we can flag
// AssociatePublicIpAddress to get a Public IP assigned. By default these are not provided.
// You cannot specify both SubnetId and the NetworkInterface.0.* parameters though, otherwise
Expand Down
66 changes: 66 additions & 0 deletions builtin/providers/aws/resource_aws_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,43 @@ func driftTags(instance *ec2.Instance) resource.TestCheckFunc {
}
}

func TestAccAWSInstance_withNetworkInterface(t *testing.T) {
var before ec2.Instance
var after ec2.Instance

testCheckPrivateIP := func(ip string, v *ec2.Instance) resource.TestCheckFunc {
return func(*terraform.State) error {
if *v.PrivateIpAddress != ip {
return fmt.Errorf("bad private IP: %s, expected: %s", *v.PrivateIpAddress, ip)
}

return nil
}
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceConfigWithNetworkInterface("test1"),
Check: resource.ComposeTestCheckFunc(
testAccCheckInstanceExists("aws_instance.foo", &before),
testCheckPrivateIP("10.1.1.11", &before),
),
},
{
Config: testAccInstanceConfigWithNetworkInterface("test2"),
Check: resource.ComposeTestCheckFunc(
testAccCheckInstanceExists("aws_instance.foo", &after),
testCheckPrivateIP("10.1.1.12", &after),
),
},
},
})
}

const testAccInstanceConfig_pre = `
resource "aws_security_group" "tf_test_foo" {
name = "tf_test_foo"
Expand Down Expand Up @@ -1505,3 +1542,32 @@ resource "aws_instance" "foo" {
subnet_id = "${aws_subnet.foo.id}"
}
`

func testAccInstanceConfigWithNetworkInterface(eni string) string {
return fmt.Sprintf(`
resource "aws_vpc" "foo" {
cidr_block = "10.1.0.0/16"
}

resource "aws_subnet" "foo" {
cidr_block = "10.1.1.0/24"
vpc_id = "${aws_vpc.foo.id}"
}

resource "aws_network_interface" "test1" {
subnet_id = "${aws_subnet.foo.id}"
private_ips = ["10.1.1.11"]
}

resource "aws_network_interface" "test2" {
subnet_id = "${aws_subnet.foo.id}"
private_ips = ["10.1.1.12"]
}

resource "aws_instance" "foo" {
ami = "ami-22b9a343"
instance_type = "t2.micro"
network_interface_id = "${aws_network_interface.%s.id}"
}
`, eni)
}
1 change: 1 addition & 0 deletions website/source/docs/providers/aws/r/instance.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ instances. See [Shutdown Behavior](https://docs.aws.amazon.com/AWSEC2/latest/Use
If you are creating Instances in a VPC, use `vpc_security_group_ids` instead.
* `vpc_security_group_ids` - (Optional) A list of security group IDs to associate with.
* `subnet_id` - (Optional) The VPC Subnet ID to launch in.
* `network_interface_id` - (Optional) The network interface ID to attach to the instance.
* `associate_public_ip_address` - (Optional) Associate a public ip address with an instance in a VPC. Boolean value.
* `private_ip` - (Optional) Private IP address to associate with the
instance in a VPC.
Expand Down