Merge pull request #1721 from managedbyq/aws_dhcp_options
providers/aws: Implements DHCP Options Set support.
This commit is contained in:
commit
d230cfb907
|
@ -105,6 +105,8 @@ func Provider() terraform.ResourceProvider {
|
||||||
"aws_subnet": resourceAwsSubnet(),
|
"aws_subnet": resourceAwsSubnet(),
|
||||||
"aws_vpc": resourceAwsVpc(),
|
"aws_vpc": resourceAwsVpc(),
|
||||||
"aws_vpc_peering_connection": resourceAwsVpcPeeringConnection(),
|
"aws_vpc_peering_connection": resourceAwsVpcPeeringConnection(),
|
||||||
|
"aws_vpc_dhcp_options": resourceAwsVpcDhcpOptions(),
|
||||||
|
"aws_vpc_dhcp_options_association": resourceAwsVpcDhcpOptionsAssociation(),
|
||||||
"aws_vpn_gateway": resourceAwsVpnGateway(),
|
"aws_vpn_gateway": resourceAwsVpnGateway(),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,11 @@ func resourceAwsVpc() *schema.Resource {
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"dhcp_options_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
"default_security_group_id": &schema.Schema{
|
"default_security_group_id": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
@ -126,6 +131,7 @@ func resourceAwsVpcRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
vpc := vpcRaw.(*ec2.VPC)
|
vpc := vpcRaw.(*ec2.VPC)
|
||||||
vpcid := d.Id()
|
vpcid := d.Id()
|
||||||
d.Set("cidr_block", vpc.CIDRBlock)
|
d.Set("cidr_block", vpc.CIDRBlock)
|
||||||
|
d.Set("dhcp_options_id", vpc.DHCPOptionsID)
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
d.Set("tags", tagsToMapSDK(vpc.Tags))
|
d.Set("tags", tagsToMapSDK(vpc.Tags))
|
||||||
|
|
|
@ -0,0 +1,280 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/awslabs/aws-sdk-go/aws"
|
||||||
|
"github.com/awslabs/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsVpcDhcpOptions() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsVpcDhcpOptionsCreate,
|
||||||
|
Read: resourceAwsVpcDhcpOptionsRead,
|
||||||
|
Update: resourceAwsVpcDhcpOptionsUpdate,
|
||||||
|
Delete: resourceAwsVpcDhcpOptionsDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"domain_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"domain_name_servers": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
|
||||||
|
"ntp_servers": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
|
||||||
|
"netbios_node_type": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"netbios_name_servers": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
|
||||||
|
"tags": &schema.Schema{
|
||||||
|
Type: schema.TypeMap,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsVpcDhcpOptionsCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
setDHCPOption := func(key string) *ec2.NewDHCPConfiguration {
|
||||||
|
log.Printf("[DEBUG] Setting DHCP option %s...", key)
|
||||||
|
tfKey := strings.Replace(key, "-", "_", -1)
|
||||||
|
|
||||||
|
value, ok := d.GetOk(tfKey)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := value.(string); ok {
|
||||||
|
return &ec2.NewDHCPConfiguration{
|
||||||
|
Key: aws.String(key),
|
||||||
|
Values: []*string{
|
||||||
|
aws.String(v),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := value.([]interface{}); ok {
|
||||||
|
var s []*string
|
||||||
|
for _, attr := range v {
|
||||||
|
s = append(s, aws.String(attr.(string)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ec2.NewDHCPConfiguration{
|
||||||
|
Key: aws.String(key),
|
||||||
|
Values: s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := &ec2.CreateDHCPOptionsInput{
|
||||||
|
DHCPConfigurations: []*ec2.NewDHCPConfiguration{
|
||||||
|
setDHCPOption("domain-name"),
|
||||||
|
setDHCPOption("domain-name-servers"),
|
||||||
|
setDHCPOption("ntp-servers"),
|
||||||
|
setDHCPOption("netbios-node-type"),
|
||||||
|
setDHCPOption("netbios-name-servers"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := conn.CreateDHCPOptions(createOpts)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating DHCP Options Set: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dos := resp.DHCPOptions
|
||||||
|
d.SetId(*dos.DHCPOptionsID)
|
||||||
|
log.Printf("[INFO] DHCP Options Set ID: %s", d.Id())
|
||||||
|
|
||||||
|
// Wait for the DHCP Options to become available
|
||||||
|
log.Printf("[DEBUG] Waiting for DHCP Options (%s) to become available", d.Id())
|
||||||
|
stateConf := &resource.StateChangeConf{
|
||||||
|
Pending: []string{"pending"},
|
||||||
|
Target: "",
|
||||||
|
Refresh: DHCPOptionsStateRefreshFunc(conn, d.Id()),
|
||||||
|
Timeout: 1 * time.Minute,
|
||||||
|
}
|
||||||
|
if _, err := stateConf.WaitForState(); err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Error waiting for DHCP Options (%s) to become available: %s",
|
||||||
|
d.Id(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceAwsVpcDhcpOptionsUpdate(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsVpcDhcpOptionsRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
req := &ec2.DescribeDHCPOptionsInput{
|
||||||
|
DHCPOptionsIDs: []*string{
|
||||||
|
aws.String(d.Id()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := conn.DescribeDHCPOptions(req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error retrieving DHCP Options: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.DHCPOptions) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := resp.DHCPOptions[0]
|
||||||
|
d.Set("tags", tagsToMapSDK(opts.Tags))
|
||||||
|
|
||||||
|
for _, cfg := range opts.DHCPConfigurations {
|
||||||
|
tfKey := strings.Replace(*cfg.Key, "-", "_", -1)
|
||||||
|
|
||||||
|
if _, ok := d.Get(tfKey).(string); ok {
|
||||||
|
d.Set(tfKey, cfg.Values[0].Value)
|
||||||
|
} else {
|
||||||
|
values := make([]string, 0, len(cfg.Values))
|
||||||
|
for _, v := range cfg.Values {
|
||||||
|
values = append(values, *v.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set(tfKey, values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsVpcDhcpOptionsUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
return setTagsSDK(conn, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsVpcDhcpOptionsDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
return resource.Retry(3*time.Minute, func() error {
|
||||||
|
log.Printf("[INFO] Deleting DHCP Options ID %s...", d.Id())
|
||||||
|
_, err := conn.DeleteDHCPOptions(&ec2.DeleteDHCPOptionsInput{
|
||||||
|
DHCPOptionsID: aws.String(d.Id()),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[WARN] %s", err)
|
||||||
|
|
||||||
|
ec2err, ok := err.(aws.APIError)
|
||||||
|
if !ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ec2err.Code {
|
||||||
|
case "InvalidDhcpOptionsID.NotFound":
|
||||||
|
return nil
|
||||||
|
case "DependencyViolation":
|
||||||
|
// If it is a dependency violation, we want to disassociate
|
||||||
|
// all VPCs using the given DHCP Options ID, and retry deleting.
|
||||||
|
vpcs, err2 := findVPCsByDHCPOptionsID(conn, d.Id())
|
||||||
|
if err2 != nil {
|
||||||
|
log.Printf("[ERROR] %s", err2)
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, vpc := range vpcs {
|
||||||
|
log.Printf("[INFO] Disassociating DHCP Options Set %s from VPC %s...", d.Id(), *vpc.VPCID)
|
||||||
|
if _, err := conn.AssociateDHCPOptions(&ec2.AssociateDHCPOptionsInput{
|
||||||
|
DHCPOptionsID: aws.String("default"),
|
||||||
|
VPCID: vpc.VPCID,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err //retry
|
||||||
|
default:
|
||||||
|
// Any other error, we want to quit the retry loop immediately
|
||||||
|
return resource.RetryError{Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func findVPCsByDHCPOptionsID(conn *ec2.EC2, id string) ([]*ec2.VPC, error) {
|
||||||
|
req := &ec2.DescribeVPCsInput{
|
||||||
|
Filters: []*ec2.Filter{
|
||||||
|
&ec2.Filter{
|
||||||
|
Name: aws.String("dhcp-options-id"),
|
||||||
|
Values: []*string{
|
||||||
|
aws.String(id),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := conn.DescribeVPCs(req)
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "InvalidVpcID.NotFound" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.VPCs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DHCPOptionsStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc {
|
||||||
|
return func() (interface{}, string, error) {
|
||||||
|
DescribeDhcpOpts := &ec2.DescribeDHCPOptionsInput{
|
||||||
|
DHCPOptionsIDs: []*string{
|
||||||
|
aws.String(id),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := conn.DescribeDHCPOptions(DescribeDhcpOpts)
|
||||||
|
if err != nil {
|
||||||
|
if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "InvalidDhcpOptionsID.NotFound" {
|
||||||
|
resp = nil
|
||||||
|
} else {
|
||||||
|
log.Printf("Error on DHCPOptionsStateRefresh: %s", err)
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp == nil {
|
||||||
|
// Sometimes AWS just has consistency issues and doesn't see
|
||||||
|
// our instance yet. Return an empty state.
|
||||||
|
return nil, "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dos := resp.DHCPOptions[0]
|
||||||
|
return dos, "", nil
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/awslabs/aws-sdk-go/aws"
|
||||||
|
"github.com/awslabs/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsVpcDhcpOptionsAssociation() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsVpcDhcpOptionsAssociationCreate,
|
||||||
|
Read: resourceAwsVpcDhcpOptionsAssociationRead,
|
||||||
|
Update: resourceAwsVpcDhcpOptionsAssociationUpdate,
|
||||||
|
Delete: resourceAwsVpcDhcpOptionsAssociationDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"vpc_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"dhcp_options_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsVpcDhcpOptionsAssociationCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
log.Printf(
|
||||||
|
"[INFO] Creating DHCP Options association: %s => %s",
|
||||||
|
d.Get("vpc_id").(string),
|
||||||
|
d.Get("dhcp_options_id").(string))
|
||||||
|
|
||||||
|
optsID := aws.String(d.Get("dhcp_options_id").(string))
|
||||||
|
vpcID := aws.String(d.Get("vpc_id").(string))
|
||||||
|
|
||||||
|
if _, err := conn.AssociateDHCPOptions(&ec2.AssociateDHCPOptionsInput{
|
||||||
|
DHCPOptionsID: optsID,
|
||||||
|
VPCID: vpcID,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the ID and return
|
||||||
|
d.SetId(*optsID + "-" + *vpcID)
|
||||||
|
log.Printf("[INFO] Association ID: %s", d.Id())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsVpcDhcpOptionsAssociationRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
// Get the VPC that this association belongs to
|
||||||
|
vpcRaw, _, err := VPCStateRefreshFunc(conn, d.Get("vpc_id").(string))()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if vpcRaw == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
vpc := vpcRaw.(*ec2.VPC)
|
||||||
|
if *vpc.VPCID != d.Get("vpc_id") || *vpc.DHCPOptionsID != d.Get("dhcp_options_id") {
|
||||||
|
log.Printf("[INFO] It seems the DHCP Options association is gone. Deleting reference from Graph...")
|
||||||
|
d.SetId("")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCP Options Asociations cannot be updated.
|
||||||
|
func resourceAwsVpcDhcpOptionsAssociationUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
return resourceAwsVpcDhcpOptionsAssociationCreate(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AWS does not provide an API to disassociate a DHCP Options set from a VPC.
|
||||||
|
// So, we do this by setting the VPC to the default DHCP Options Set.
|
||||||
|
func resourceAwsVpcDhcpOptionsAssociationDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
log.Printf("[INFO] Disassociating DHCP Options Set %s from VPC %s...", d.Get("dhcp_options_id"), d.Get("vpc_id"))
|
||||||
|
if _, err := conn.AssociateDHCPOptions(&ec2.AssociateDHCPOptionsInput{
|
||||||
|
DHCPOptionsID: aws.String("default"),
|
||||||
|
VPCID: aws.String(d.Get("vpc_id").(string)),
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/awslabs/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSDHCPOptionsAssociation(t *testing.T) {
|
||||||
|
var v ec2.VPC
|
||||||
|
var d ec2.DHCPOptions
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckDHCPOptionsAssociationDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccDHCPOptionsAssociationConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckDHCPOptionsExists("aws_vpc_dhcp_options.foo", &d),
|
||||||
|
testAccCheckVpcExists("aws_vpc.foo", &v),
|
||||||
|
testAccCheckDHCPOptionsAssociationExist("aws_vpc_dhcp_options_association.foo", &v),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckDHCPOptionsAssociationDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "aws_vpc_dhcp_options_association" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the VPC associated to the DHCP Options set
|
||||||
|
vpcs, err := findVPCsByDHCPOptionsID(conn, rs.Primary.Attributes["dhcp_options_id"])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(vpcs) > 0 {
|
||||||
|
return fmt.Errorf("DHCP Options association is still associated to %d VPCs.", len(vpcs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckDHCPOptionsAssociationExist(n string, vpc *ec2.VPC) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No DHCP Options Set association ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if *vpc.DHCPOptionsID != rs.Primary.Attributes["dhcp_options_id"] {
|
||||||
|
return fmt.Errorf("VPC %s does not have DHCP Options Set %s associated", *vpc.VPCID, rs.Primary.Attributes["dhcp_options_id"])
|
||||||
|
}
|
||||||
|
|
||||||
|
if *vpc.VPCID != rs.Primary.Attributes["vpc_id"] {
|
||||||
|
return fmt.Errorf("DHCP Options Set %s is not associated with VPC %s", rs.Primary.Attributes["dhcp_options_id"], *vpc.VPCID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccDHCPOptionsAssociationConfig = `
|
||||||
|
resource "aws_vpc" "foo" {
|
||||||
|
cidr_block = "10.1.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_vpc_dhcp_options" "foo" {
|
||||||
|
domain_name = "service.consul"
|
||||||
|
domain_name_servers = ["127.0.0.1", "10.0.0.2"]
|
||||||
|
ntp_servers = ["127.0.0.1"]
|
||||||
|
netbios_name_servers = ["127.0.0.1"]
|
||||||
|
netbios_node_type = 2
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_vpc_dhcp_options_association" "foo" {
|
||||||
|
vpc_id = "${aws_vpc.foo.id}"
|
||||||
|
dhcp_options_id = "${aws_vpc_dhcp_options.foo.id}"
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,115 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/awslabs/aws-sdk-go/aws"
|
||||||
|
"github.com/awslabs/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccDHCPOptions(t *testing.T) {
|
||||||
|
var d ec2.DHCPOptions
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckDHCPOptionsDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccDHCPOptionsConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckDHCPOptionsExists("aws_vpc_dhcp_options.foo", &d),
|
||||||
|
resource.TestCheckResourceAttr("aws_vpc_dhcp_options.foo", "domain_name", "service.consul"),
|
||||||
|
resource.TestCheckResourceAttr("aws_vpc_dhcp_options.foo", "domain_name_servers.0", "127.0.0.1"),
|
||||||
|
resource.TestCheckResourceAttr("aws_vpc_dhcp_options.foo", "domain_name_servers.1", "10.0.0.2"),
|
||||||
|
resource.TestCheckResourceAttr("aws_vpc_dhcp_options.foo", "ntp_servers.0", "127.0.0.1"),
|
||||||
|
resource.TestCheckResourceAttr("aws_vpc_dhcp_options.foo", "netbios_name_servers.0", "127.0.0.1"),
|
||||||
|
resource.TestCheckResourceAttr("aws_vpc_dhcp_options.foo", "netbios_node_type", "2"),
|
||||||
|
resource.TestCheckResourceAttr("aws_vpc_dhcp_options.foo", "tags.Name", "foo-name"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckDHCPOptionsDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "aws_vpc_dhcp_options" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the resource
|
||||||
|
resp, err := conn.DescribeDHCPOptions(&ec2.DescribeDHCPOptionsInput{
|
||||||
|
DHCPOptionsIDs: []*string{
|
||||||
|
aws.String(rs.Primary.ID),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
if len(resp.DHCPOptions) > 0 {
|
||||||
|
return fmt.Errorf("still exist.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the error is what we want
|
||||||
|
ec2err, ok := err.(aws.APIError)
|
||||||
|
if !ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ec2err.Code != "InvalidDhcpOptionsID.NotFound" {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckDHCPOptionsExists(n string, d *ec2.DHCPOptions) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
||||||
|
resp, err := conn.DescribeDHCPOptions(&ec2.DescribeDHCPOptionsInput{
|
||||||
|
DHCPOptionsIDs: []*string{
|
||||||
|
aws.String(rs.Primary.ID),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(resp.DHCPOptions) == 0 {
|
||||||
|
return fmt.Errorf("DHCP Options not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
*d = *resp.DHCPOptions[0]
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccDHCPOptionsConfig = `
|
||||||
|
resource "aws_vpc_dhcp_options" "foo" {
|
||||||
|
domain_name = "service.consul"
|
||||||
|
domain_name_servers = ["127.0.0.1", "10.0.0.2"]
|
||||||
|
ntp_servers = ["127.0.0.1"]
|
||||||
|
netbios_name_servers = ["127.0.0.1"]
|
||||||
|
netbios_node_type = 2
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "foo-name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_vpc_dhcp_options"
|
||||||
|
sidebar_current: "docs-aws-resource-vpc-dhcp-options"
|
||||||
|
description: |-
|
||||||
|
Provides a VPC DHCP Options resource.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_vpc\_dhcp\_options
|
||||||
|
|
||||||
|
Provides a VPC DHCP Options resource.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
Basic usage:
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_vpc_dhcp_options" "dns_resolver" {
|
||||||
|
domain_name_servers = ["8.8.8.8", "8.8.4.4"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Full usage:
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_vpc_dhcp_options" "foo" {
|
||||||
|
domain_name = "service.consul"
|
||||||
|
domain_name_servers = ["127.0.0.1", "10.0.0.2"]
|
||||||
|
ntp_servers = ["127.0.0.1"]
|
||||||
|
netbios_name_servers = ["127.0.0.1"]
|
||||||
|
netbios_node_type = 2
|
||||||
|
|
||||||
|
tags {
|
||||||
|
Name = "foo-name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `domain_name` - (Optional) the suffix domain name to use by default when resolving non Fully Qualified Domain Names. In other words, this is what ends up being the `search` value in the `/etc/resolv.conf` file.
|
||||||
|
* `domain_name_servers` - (Optional) List of name servers to configure in `/etc/resolv.conf`.
|
||||||
|
* `ntp_servers` - (Optional) List of NTP servers to configure.
|
||||||
|
* `netbios_name_servers` - (Optional) List of NETBIOS name servers.
|
||||||
|
* `netbios_node_type` - (Optional) The NetBIOS node type (1, 2, 4, or 8). AWS recommends to specify 2 since broadcast and multicast are not supported in their network. For more information about these node types, see [RFC 2132](http://www.ietf.org/rfc/rfc2132.txt).
|
||||||
|
* `tags` - (Optional) A mapping of tags to assign to the resource.
|
||||||
|
|
||||||
|
## Remarks
|
||||||
|
* Notice that all arguments are optional but you have to specify at least one argument.
|
||||||
|
* `domain_name_servers`, `netbios_name_servers`, `ntp_servers` are limited by AWS to maximum four servers only.
|
||||||
|
* To actually use the DHCP Options Set you need to associate it to a VPC using [`aws_vpc_dhcp_options_association`](/docs/providers/aws/r/vpc_dhcp_options_association.html).
|
||||||
|
* If you delete a DHCP Options Set, all VPCs using it will be associated to AWS's `default` DHCP Option Set.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the DHCP Options Set.
|
||||||
|
|
||||||
|
## Known Issues
|
||||||
|
* https://github.com/awslabs/aws-sdk-go/issues/210
|
||||||
|
|
||||||
|
You can find more technical documentation about DHCP Options Set in the
|
||||||
|
official [AWS User Guide](http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html).
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_vpc_dhcp_options_association"
|
||||||
|
sidebar_current: "docs-aws-resource-vpc-dhcp-options-association"
|
||||||
|
description: |-
|
||||||
|
Provides a VPC DHCP Options Association resource.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_vpc\_dhcp\_options\_<wbr>association
|
||||||
|
|
||||||
|
Provides a VPC DHCP Options Association resource.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_vpc_dhcp_options_association" "dns_resolver" {
|
||||||
|
vpc_id = "${aws_vpc.foo.id}"
|
||||||
|
dhcp_options_id = "${aws_vpc_dhcp_options.foo.id}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `vpc_id` - (Required) The ID of the VPC to which we would like to associate a DHCP Options Set.
|
||||||
|
* `dhcp_options_id` - (Required) The ID of the DHCP Options Set to associate to the VPC.
|
||||||
|
|
||||||
|
## Remarks
|
||||||
|
* You can only associate one DHCP Options Set to a given VPC ID.
|
||||||
|
* Removing the DHCP Options Association automatically sets AWS's `default` DHCP Options Set to the VPC.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the DHCP Options Set Association.
|
|
@ -110,13 +110,21 @@
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-vpc-peering") %>>
|
<li<%= sidebar_current("docs-aws-resource-vpc-peering") %>>
|
||||||
<a href="/docs/providers/aws/r/vpc_peering.html">aws_vpc_peering</a>
|
<a href="/docs/providers/aws/r/vpc_peering.html">aws_vpc_peering</a>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-vpn-gateway") %>>
|
|
||||||
<a href="/docs/providers/aws/r/vpn_gateway.html">aws_vpn_gateway</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-aws-resource-vpc-dhcp-options") %>>
|
||||||
|
<a href="/docs/providers/aws/r/vpc_dhcp_options.html">aws_vpc_dhcp_options</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-aws-resource-vpc-dhcp-options-association") %>>
|
||||||
|
<a href="/docs/providers/aws/r/vpc_dhcp_options_association.html">aws_vpc_dhcp_options_association</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-aws-resource-vpn-gateway") %>>
|
||||||
|
<a href="/docs/providers/aws/r/vpn_gateway.html">aws_vpn_gateway</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
Loading…
Reference in New Issue