diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 9efc95a04..4e2c2b570 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -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(), }, diff --git a/builtin/providers/aws/resource_aws_vpc.go b/builtin/providers/aws/resource_aws_vpc.go index 14e552182..d27bde533 100644 --- a/builtin/providers/aws/resource_aws_vpc.go +++ b/builtin/providers/aws/resource_aws_vpc.go @@ -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)) diff --git a/builtin/providers/aws/resource_aws_vpc_dhcp_options.go b/builtin/providers/aws/resource_aws_vpc_dhcp_options.go new file mode 100644 index 000000000..c496b1eb8 --- /dev/null +++ b/builtin/providers/aws/resource_aws_vpc_dhcp_options.go @@ -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 + } +} diff --git a/builtin/providers/aws/resource_aws_vpc_dhcp_options_association.go b/builtin/providers/aws/resource_aws_vpc_dhcp_options_association.go new file mode 100644 index 000000000..46c447213 --- /dev/null +++ b/builtin/providers/aws/resource_aws_vpc_dhcp_options_association.go @@ -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 +} diff --git a/builtin/providers/aws/resource_aws_vpc_dhcp_options_association_test.go b/builtin/providers/aws/resource_aws_vpc_dhcp_options_association_test.go new file mode 100644 index 000000000..1b00ce3dc --- /dev/null +++ b/builtin/providers/aws/resource_aws_vpc_dhcp_options_association_test.go @@ -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}" +} +` diff --git a/builtin/providers/aws/resource_aws_vpc_dhcp_options_test.go b/builtin/providers/aws/resource_aws_vpc_dhcp_options_test.go new file mode 100644 index 000000000..74ab93953 --- /dev/null +++ b/builtin/providers/aws/resource_aws_vpc_dhcp_options_test.go @@ -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" + } +} +` diff --git a/website/source/docs/providers/aws/r/vpc_dhcp_options.html.markdown b/website/source/docs/providers/aws/r/vpc_dhcp_options.html.markdown new file mode 100644 index 000000000..3e595adcc --- /dev/null +++ b/website/source/docs/providers/aws/r/vpc_dhcp_options.html.markdown @@ -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). diff --git a/website/source/docs/providers/aws/r/vpc_dhcp_options_association.html.markdown b/website/source/docs/providers/aws/r/vpc_dhcp_options_association.html.markdown new file mode 100644 index 000000000..ee0cfe3e2 --- /dev/null +++ b/website/source/docs/providers/aws/r/vpc_dhcp_options_association.html.markdown @@ -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\_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. diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index eeaaaff85..b10ac513a 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -110,13 +110,21 @@ > aws_vpc_peering - - > - aws_vpn_gateway - - - + + > + aws_vpc_dhcp_options + + + > + aws_vpc_dhcp_options_association + + + > + aws_vpn_gateway + + + <% end %>