diff --git a/aws/resource_aws_ec2_client_vpn_endpoint.go b/aws/resource_aws_ec2_client_vpn_endpoint.go index dae8f29ffd3..bc34139e0fc 100644 --- a/aws/resource_aws_ec2_client_vpn_endpoint.go +++ b/aws/resource_aws_ec2_client_vpn_endpoint.go @@ -5,6 +5,7 @@ import ( "log" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" @@ -27,9 +28,10 @@ func resourceAwsEc2ClientVpnEndpoint() *schema.Resource { Optional: true, }, "client_cidr_block": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsCIDR, }, "dns_servers": { Type: schema.TypeSet, @@ -37,8 +39,9 @@ func resourceAwsEc2ClientVpnEndpoint() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, "server_certificate_arn": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, }, "split_tunnel": { Type: schema.TypeBool, @@ -76,9 +79,10 @@ func resourceAwsEc2ClientVpnEndpoint() *schema.Resource { ForceNew: true, }, "root_certificate_chain_arn": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validateArn, }, }, }, @@ -113,6 +117,10 @@ func resourceAwsEc2ClientVpnEndpoint() *schema.Resource { Computed: true, }, "tags": tagsSchema(), + "arn": { + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -239,6 +247,16 @@ func resourceAwsEc2ClientVpnEndpointRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("error setting tags: %s", err) } + arn := arn.ARN{ + Partition: meta.(*AWSClient).partition, + Service: "ec2", + Region: meta.(*AWSClient).region, + AccountID: meta.(*AWSClient).accountid, + Resource: fmt.Sprintf("client-vpn-endpoint/%s", d.Id()), + }.String() + + d.Set("arn", arn) + return nil } diff --git a/aws/resource_aws_ec2_client_vpn_endpoint_test.go b/aws/resource_aws_ec2_client_vpn_endpoint_test.go index b712a45cc40..fd80deda7dd 100644 --- a/aws/resource_aws_ec2_client_vpn_endpoint_test.go +++ b/aws/resource_aws_ec2_client_vpn_endpoint_test.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "log" + "regexp" "testing" "github.com/aws/aws-sdk-go/aws" @@ -74,6 +75,7 @@ func testSweepEc2ClientVpnEndpoints(region string) error { func TestAccAwsEc2ClientVpnEndpoint_basic(t *testing.T) { rStr := acctest.RandString(5) + resourceName := "aws_ec2_client_vpn_endpoint.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -83,15 +85,16 @@ func TestAccAwsEc2ClientVpnEndpoint_basic(t *testing.T) { { Config: testAccEc2ClientVpnEndpointConfig(rStr), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsEc2ClientVpnEndpointExists("aws_ec2_client_vpn_endpoint.test"), - resource.TestCheckResourceAttr("aws_ec2_client_vpn_endpoint.test", "authentication_options.#", "1"), - resource.TestCheckResourceAttr("aws_ec2_client_vpn_endpoint.test", "authentication_options.0.type", "certificate-authentication"), - resource.TestCheckResourceAttr("aws_ec2_client_vpn_endpoint.test", "status", ec2.ClientVpnEndpointStatusCodePendingAssociate), + testAccCheckAwsEc2ClientVpnEndpointExists(resourceName), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`client-vpn-endpoint/cvpn-endpoint-.+`)), + resource.TestCheckResourceAttr(resourceName, "authentication_options.#", "1"), + resource.TestCheckResourceAttr(resourceName, "authentication_options.0.type", "certificate-authentication"), + resource.TestCheckResourceAttr(resourceName, "status", ec2.ClientVpnEndpointStatusCodePendingAssociate), ), }, { - ResourceName: "aws_ec2_client_vpn_endpoint.test", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, }, @@ -101,6 +104,7 @@ func TestAccAwsEc2ClientVpnEndpoint_basic(t *testing.T) { func TestAccAwsEc2ClientVpnEndpoint_disappears(t *testing.T) { rStr := acctest.RandString(5) + resourceName := "aws_ec2_client_vpn_endpoint.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -110,8 +114,8 @@ func TestAccAwsEc2ClientVpnEndpoint_disappears(t *testing.T) { { Config: testAccEc2ClientVpnEndpointConfig(rStr), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsEc2ClientVpnEndpointExists("aws_ec2_client_vpn_endpoint.test"), - testAccCheckAwsEc2ClientVpnEndpointDisappears("aws_ec2_client_vpn_endpoint.test"), + testAccCheckAwsEc2ClientVpnEndpointExists(resourceName), + testAccCheckResourceDisappears(testAccProvider, resourceAwsEc2ClientVpnEndpoint(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -121,6 +125,7 @@ func TestAccAwsEc2ClientVpnEndpoint_disappears(t *testing.T) { func TestAccAwsEc2ClientVpnEndpoint_msAD(t *testing.T) { rStr := acctest.RandString(5) + resourceName := "aws_ec2_client_vpn_endpoint.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -130,14 +135,14 @@ func TestAccAwsEc2ClientVpnEndpoint_msAD(t *testing.T) { { Config: testAccEc2ClientVpnEndpointConfigWithMicrosoftAD(rStr), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsEc2ClientVpnEndpointExists("aws_ec2_client_vpn_endpoint.test"), - resource.TestCheckResourceAttr("aws_ec2_client_vpn_endpoint.test", "authentication_options.#", "1"), - resource.TestCheckResourceAttr("aws_ec2_client_vpn_endpoint.test", "authentication_options.0.type", "directory-service-authentication"), + testAccCheckAwsEc2ClientVpnEndpointExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "authentication_options.#", "1"), + resource.TestCheckResourceAttr(resourceName, "authentication_options.0.type", "directory-service-authentication"), ), }, { - ResourceName: "aws_ec2_client_vpn_endpoint.test", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, }, @@ -147,6 +152,7 @@ func TestAccAwsEc2ClientVpnEndpoint_msAD(t *testing.T) { func TestAccAwsEc2ClientVpnEndpoint_mutualAuthAndMsAD(t *testing.T) { rStr := acctest.RandString(5) + resourceName := "aws_ec2_client_vpn_endpoint.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -156,15 +162,15 @@ func TestAccAwsEc2ClientVpnEndpoint_mutualAuthAndMsAD(t *testing.T) { { Config: testAccEc2ClientVpnEndpointConfigWithMutualAuthAndMicrosoftAD(rStr), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsEc2ClientVpnEndpointExists("aws_ec2_client_vpn_endpoint.test"), - resource.TestCheckResourceAttr("aws_ec2_client_vpn_endpoint.test", "authentication_options.#", "2"), - resource.TestCheckResourceAttr("aws_ec2_client_vpn_endpoint.test", "authentication_options.0.type", "directory-service-authentication"), - resource.TestCheckResourceAttr("aws_ec2_client_vpn_endpoint.test", "authentication_options.1.type", "certificate-authentication"), + testAccCheckAwsEc2ClientVpnEndpointExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "authentication_options.#", "2"), + resource.TestCheckResourceAttr(resourceName, "authentication_options.0.type", "directory-service-authentication"), + resource.TestCheckResourceAttr(resourceName, "authentication_options.1.type", "certificate-authentication"), ), }, { - ResourceName: "aws_ec2_client_vpn_endpoint.test", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, }, @@ -174,6 +180,7 @@ func TestAccAwsEc2ClientVpnEndpoint_mutualAuthAndMsAD(t *testing.T) { func TestAccAwsEc2ClientVpnEndpoint_withLogGroup(t *testing.T) { rStr := acctest.RandString(5) + resourceName := "aws_ec2_client_vpn_endpoint.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -183,19 +190,19 @@ func TestAccAwsEc2ClientVpnEndpoint_withLogGroup(t *testing.T) { { Config: testAccEc2ClientVpnEndpointConfig(rStr), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsEc2ClientVpnEndpointExists("aws_ec2_client_vpn_endpoint.test"), + testAccCheckAwsEc2ClientVpnEndpointExists(resourceName), ), }, { Config: testAccEc2ClientVpnEndpointConfigWithLogGroup(rStr), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsEc2ClientVpnEndpointExists("aws_ec2_client_vpn_endpoint.test"), + testAccCheckAwsEc2ClientVpnEndpointExists(resourceName), ), }, { - ResourceName: "aws_ec2_client_vpn_endpoint.test", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, }, @@ -205,6 +212,7 @@ func TestAccAwsEc2ClientVpnEndpoint_withLogGroup(t *testing.T) { func TestAccAwsEc2ClientVpnEndpoint_withDNSServers(t *testing.T) { rStr := acctest.RandString(5) + resourceName := "aws_ec2_client_vpn_endpoint.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -214,19 +222,19 @@ func TestAccAwsEc2ClientVpnEndpoint_withDNSServers(t *testing.T) { { Config: testAccEc2ClientVpnEndpointConfig(rStr), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsEc2ClientVpnEndpointExists("aws_ec2_client_vpn_endpoint.test"), + testAccCheckAwsEc2ClientVpnEndpointExists(resourceName), ), }, { Config: testAccEc2ClientVpnEndpointConfigWithDNSServers(rStr), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsEc2ClientVpnEndpointExists("aws_ec2_client_vpn_endpoint.test"), + testAccCheckAwsEc2ClientVpnEndpointExists(resourceName), ), }, { - ResourceName: "aws_ec2_client_vpn_endpoint.test", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, }, @@ -251,6 +259,11 @@ func TestAccAwsEc2ClientVpnEndpoint_tags(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.Usage", "original"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccEc2ClientVpnEndpointConfig_tagsChanged(rStr), Check: resource.ComposeTestCheckFunc( @@ -324,25 +337,6 @@ func testAccCheckAwsEc2ClientVpnEndpointDestroy(s *terraform.State) error { return nil } -func testAccCheckAwsEc2ClientVpnEndpointDisappears(name string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] - if !ok { - return fmt.Errorf("Not found: %s", name) - } - - conn := testAccProvider.Meta().(*AWSClient).ec2conn - - input := &ec2.DeleteClientVpnEndpointInput{ - ClientVpnEndpointId: aws.String(rs.Primary.ID), - } - - _, err := conn.DeleteClientVpnEndpoint(input) - - return err - } -} - func testAccCheckAwsEc2ClientVpnEndpointExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { _, ok := s.RootModule().Resources[name] diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 8f5b0b928bd..9e15dd3fdef 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -246,6 +246,7 @@ for more information about connecting to alternate AWS endpoints or AWS compatib - [`aws_dx_public_virtual_interface` resource](/docs/providers/aws/r/dx_public_virtual_interface.html) - [`aws_dx_transit_virtual_interface` resource](/docs/providers/aws/r/dx_transit_virtual_interface.html) - [`aws_ebs_volume` data source](/docs/providers/aws/d/ebs_volume.html) + - [`aws_ec2_client_vpn_endpoint` resource](/docs/providers/aws/r/ec2_client_vpn_endpoint.html) - [`aws_ecs_capacity_provider` resource (import)](/docs/providers/aws/r/ecs_capacity_provider.html) - [`aws_ecs_cluster` resource (import)](/docs/providers/aws/r/ecs_cluster.html) - [`aws_ecs_service` resource (import)](/docs/providers/aws/r/ecs_service.html) diff --git a/website/docs/r/ec2_client_vpn_endpoint.html.markdown b/website/docs/r/ec2_client_vpn_endpoint.html.markdown index 2823edeb472..c3e89b0830a 100644 --- a/website/docs/r/ec2_client_vpn_endpoint.html.markdown +++ b/website/docs/r/ec2_client_vpn_endpoint.html.markdown @@ -67,6 +67,7 @@ One of the following arguments must be supplied: In addition to all arguments above, the following attributes are exported: * `id` - The ID of the Client VPN endpoint. +* `arn` - The ARN of the Client VPN endpoint. * `dns_name` - The DNS name to be used by clients when establishing their VPN session. * `status` - The current state of the Client VPN endpoint.