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_vpc": resourceAwsVpc(),
|
||||
"aws_vpc_peering_connection": resourceAwsVpcPeeringConnection(),
|
||||
"aws_vpc_dhcp_options": resourceAwsVpcDhcpOptions(),
|
||||
"aws_vpc_dhcp_options_association": resourceAwsVpcDhcpOptionsAssociation(),
|
||||
"aws_vpn_gateway": resourceAwsVpnGateway(),
|
||||
},
|
||||
|
||||
|
|
|
@ -53,6 +53,11 @@ func resourceAwsVpc() *schema.Resource {
|
|||
Computed: true,
|
||||
},
|
||||
|
||||
"dhcp_options_id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"default_security_group_id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
|
@ -126,6 +131,7 @@ func resourceAwsVpcRead(d *schema.ResourceData, meta interface{}) error {
|
|||
vpc := vpcRaw.(*ec2.VPC)
|
||||
vpcid := d.Id()
|
||||
d.Set("cidr_block", vpc.CIDRBlock)
|
||||
d.Set("dhcp_options_id", vpc.DHCPOptionsID)
|
||||
|
||||
// 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,10 +110,18 @@
|
|||
|
||||
<li<%= sidebar_current("docs-aws-resource-vpc-peering") %>>
|
||||
<a href="/docs/providers/aws/r/vpc_peering.html">aws_vpc_peering</a>
|
||||
</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>
|
||||
|
|
Loading…
Reference in New Issue