diff --git a/.changelog/15375.txt b/.changelog/15375.txt new file mode 100644 index 000000000000..7c838e27af23 --- /dev/null +++ b/.changelog/15375.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_transfer_server: Add `security_policy_name` argument +``` \ No newline at end of file diff --git a/aws/resource_aws_transfer_server.go b/aws/resource_aws_transfer_server.go index 5cca3bf03f6f..e7eff78df712 100644 --- a/aws/resource_aws_transfer_server.go +++ b/aws/resource_aws_transfer_server.go @@ -36,14 +36,10 @@ func resourceAwsTransferServer() *schema.Resource { }, "endpoint_type": { - Type: schema.TypeString, - Optional: true, - Default: transfer.EndpointTypePublic, - ValidateFunc: validation.StringInSlice([]string{ - transfer.EndpointTypePublic, - transfer.EndpointTypeVpc, - transfer.EndpointTypeVpcEndpoint, - }, false), + Type: schema.TypeString, + Optional: true, + Default: transfer.EndpointTypePublic, + ValidateFunc: validation.StringInSlice(transfer.EndpointType_Values(), false), }, "endpoint_details": { @@ -106,14 +102,11 @@ func resourceAwsTransferServer() *schema.Resource { }, "identity_provider_type": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Default: transfer.IdentityProviderTypeServiceManaged, - ValidateFunc: validation.StringInSlice([]string{ - transfer.IdentityProviderTypeServiceManaged, - transfer.IdentityProviderTypeApiGateway, - }, false), + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: transfer.IdentityProviderTypeServiceManaged, + ValidateFunc: validation.StringInSlice(transfer.IdentityProviderType_Values(), false), }, "logging_role": { @@ -127,6 +120,16 @@ func resourceAwsTransferServer() *schema.Resource { Optional: true, Default: false, }, + "security_policy_name": { + Type: schema.TypeString, + Optional: true, + Default: "TransferSecurityPolicy-2018-11", + ValidateFunc: validation.StringInSlice([]string{ + "TransferSecurityPolicy-2018-11", + "TransferSecurityPolicy-2020-06", + "TransferSecurityPolicy-FIPS-2020-06", + }, false), + }, "tags": tagsSchema(), @@ -173,6 +176,10 @@ func resourceAwsTransferServerCreate(d *schema.ResourceData, meta interface{}) e createOpts.EndpointType = aws.String(attr.(string)) } + if attr, ok := d.GetOk("security_policy_name"); ok { + createOpts.SecurityPolicyName = aws.String(attr.(string)) + } + if attr, ok := d.GetOk("endpoint_details"); ok { createOpts.EndpointDetails = expandTransferServerEndpointDetails(attr.([]interface{})) @@ -294,6 +301,7 @@ func resourceAwsTransferServerRead(d *schema.ResourceData, meta interface{}) err d.Set("identity_provider_type", resp.Server.IdentityProviderType) d.Set("logging_role", resp.Server.LoggingRole) d.Set("host_key_fingerprint", resp.Server.HostKeyFingerprint) + d.Set("security_policy_name", resp.Server.SecurityPolicyName) tags := keyvaluetags.TransferKeyValueTags(resp.Server.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) @@ -321,6 +329,11 @@ func resourceAwsTransferServerUpdate(d *schema.ResourceData, meta interface{}) e updateOpts.LoggingRole = aws.String(d.Get("logging_role").(string)) } + if d.HasChange("security_policy_name") { + updateFlag = true + updateOpts.SecurityPolicyName = aws.String(d.Get("security_policy_name").(string)) + } + if d.HasChanges("invocation_role", "url") { identityProviderDetails := &transfer.IdentityProviderDetails{} updateFlag = true diff --git a/aws/resource_aws_transfer_server_test.go b/aws/resource_aws_transfer_server_test.go index 94b9959819da..4315dfd5893a 100644 --- a/aws/resource_aws_transfer_server_test.go +++ b/aws/resource_aws_transfer_server_test.go @@ -15,6 +15,8 @@ import ( ) func init() { + RegisterServiceErrorCheckFunc(transfer.EndpointsID, testAccErrorCheckSkipTransfer) + resource.AddTestSweepers("aws_transfer_server", &resource.Sweeper{ Name: "aws_transfer_server", F: testSweepTransferServers, @@ -64,10 +66,16 @@ func testSweepTransferServers(region string) error { return nil } +func testAccErrorCheckSkipTransfer(t *testing.T) resource.ErrorCheckFunc { + return testAccErrorCheckSkipMessagesContaining(t, + "Invalid server type: PUBLIC", + ) +} + func TestAccAWSTransferServer_basic(t *testing.T) { var conf transfer.DescribedServer - resourceName := "aws_transfer_server.foo" - rName := acctest.RandString(5) + resourceName := "aws_transfer_server.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSTransfer(t) }, @@ -76,15 +84,15 @@ func TestAccAWSTransferServer_basic(t *testing.T) { CheckDestroy: testAccCheckAWSTransferServerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSTransferServerConfig_basic, + Config: testAccAWSTransferServerBasicConfig(), Check: resource.ComposeTestCheckFunc( testAccCheckAWSTransferServerExists(resourceName, &conf), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "transfer", regexp.MustCompile(`server/.+`)), - resource.TestMatchResourceAttr( - resourceName, "endpoint", regexp.MustCompile(fmt.Sprintf("^s-[a-z0-9]+.server.transfer.%s.amazonaws.com$", testAccGetRegion()))), - resource.TestCheckResourceAttr( - resourceName, "identity_provider_type", "SERVICE_MANAGED"), + testAccMatchResourceAttrRegionalHostname(resourceName, "endpoint", "server.transfer", regexp.MustCompile(`s-[a-z0-9]+`)), + resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "endpoint_type", "PUBLIC"), + resource.TestCheckResourceAttr(resourceName, "security_policy_name", "TransferSecurityPolicy-2018-11"), ), }, { @@ -94,17 +102,45 @@ func TestAccAWSTransferServer_basic(t *testing.T) { ImportStateVerifyIgnore: []string{"force_destroy"}, }, { - Config: testAccAWSTransferServerConfig_basicUpdate(rName), + Config: testAccAWSTransferServerUpdatedConfig(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSTransferServerExists(resourceName, &conf), - resource.TestCheckResourceAttr( - resourceName, "tags.%", "2"), - resource.TestCheckResourceAttr( - resourceName, "tags.NAME", "tf-acc-test-transfer-server"), - resource.TestCheckResourceAttr( - resourceName, "tags.ENV", "test"), - resource.TestCheckResourceAttrPair( - resourceName, "logging_role", "aws_iam_role.foo", "arn"), + resource.TestCheckResourceAttrPair(resourceName, "logging_role", "aws_iam_role.test", "arn"), + resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"), + ), + }, + }, + }) +} + +func TestAccAWSTransferServer_securityPolicy(t *testing.T) { + var conf transfer.DescribedServer + resourceName := "aws_transfer_server.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSTransfer(t) }, + ErrorCheck: testAccErrorCheck(t, transfer.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSTransferServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSTransferServerSecurityPolicyConfig("TransferSecurityPolicy-2020-06"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSTransferServerExists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "security_policy_name", "TransferSecurityPolicy-2020-06"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"force_destroy"}, + }, + { + Config: testAccAWSTransferServerSecurityPolicyConfig("TransferSecurityPolicy-2018-11"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSTransferServerExists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "security_policy_name", "TransferSecurityPolicy-2018-11"), ), }, }, @@ -114,6 +150,7 @@ func TestAccAWSTransferServer_basic(t *testing.T) { func TestAccAWSTransferServer_Vpc(t *testing.T) { var conf transfer.DescribedServer resourceName := "aws_transfer_server.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSTransfer(t) }, @@ -122,15 +159,12 @@ func TestAccAWSTransferServer_Vpc(t *testing.T) { CheckDestroy: testAccCheckAWSTransferServerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSTransferServerConfig_Vpc, + Config: testAccAWSTransferServerConfig_Vpc(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSTransferServerExists(resourceName, &conf), - resource.TestCheckResourceAttr( - resourceName, "endpoint_type", "VPC"), - resource.TestCheckResourceAttr( - resourceName, "endpoint_details.0.subnet_ids.#", "1"), - resource.TestCheckResourceAttr( - resourceName, "endpoint_details.0.address_allocation_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "endpoint_type", "VPC"), + resource.TestCheckResourceAttr(resourceName, "endpoint_details.0.subnet_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "endpoint_details.0.address_allocation_ids.#", "1"), ), }, { @@ -140,13 +174,11 @@ func TestAccAWSTransferServer_Vpc(t *testing.T) { ImportStateVerifyIgnore: []string{"force_destroy"}, }, { - Config: testAccAWSTransferServerConfig_VpcUpdate, + Config: testAccAWSTransferServerConfig_VpcUpdate(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSTransferServerExists(resourceName, &conf), - resource.TestCheckResourceAttr( - resourceName, "endpoint_type", "VPC"), - resource.TestCheckResourceAttr( - resourceName, "endpoint_details.0.address_allocation_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "endpoint_type", "VPC"), + resource.TestCheckResourceAttr(resourceName, "endpoint_details.0.address_allocation_ids.#", "1"), ), }, }, @@ -155,8 +187,8 @@ func TestAccAWSTransferServer_Vpc(t *testing.T) { func TestAccAWSTransferServer_apigateway(t *testing.T) { var conf transfer.DescribedServer - resourceName := "aws_transfer_server.foo" - rName := acctest.RandString(5) + resourceName := "aws_transfer_server.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccAPIGatewayTypeEDGEPreCheck(t); testAccPreCheckAWSTransfer(t) }, @@ -168,16 +200,8 @@ func TestAccAWSTransferServer_apigateway(t *testing.T) { Config: testAccAWSTransferServerConfig_apigateway(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSTransferServerExists(resourceName, &conf), - resource.TestCheckResourceAttr( - resourceName, "identity_provider_type", "API_GATEWAY"), - resource.TestCheckResourceAttrSet( - resourceName, "invocation_role"), - resource.TestCheckResourceAttr( - resourceName, "tags.%", "2"), - resource.TestCheckResourceAttr( - resourceName, "tags.NAME", "tf-acc-test-transfer-server"), - resource.TestCheckResourceAttr( - resourceName, "tags.TYPE", "apigateway"), + resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "API_GATEWAY"), + resource.TestCheckResourceAttrPair(resourceName, "invocation_role", "aws_iam_role.test", "arn"), ), }, }, @@ -186,6 +210,7 @@ func TestAccAWSTransferServer_apigateway(t *testing.T) { func TestAccAWSTransferServer_disappears(t *testing.T) { var conf transfer.DescribedServer + resourceName := "aws_transfer_server.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSTransfer(t) }, @@ -194,10 +219,10 @@ func TestAccAWSTransferServer_disappears(t *testing.T) { CheckDestroy: testAccCheckAWSTransferServerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSTransferServerConfig_basic, + Config: testAccAWSTransferServerBasicConfig(), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSTransferServerExists("aws_transfer_server.foo", &conf), - testAccCheckAWSTransferServerDisappears(&conf), + testAccCheckAWSTransferServerExists(resourceName, &conf), + testAccCheckResourceDisappears(testAccProvider, resourceAwsTransferServer(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -208,8 +233,8 @@ func TestAccAWSTransferServer_disappears(t *testing.T) { func TestAccAWSTransferServer_forcedestroy(t *testing.T) { var conf transfer.DescribedServer var roleConf iam.GetRoleOutput - resourceName := "aws_transfer_server.foo" - rName := acctest.RandString(5) + resourceName := "aws_transfer_server.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSTransfer(t) }, @@ -221,11 +246,9 @@ func TestAccAWSTransferServer_forcedestroy(t *testing.T) { Config: testAccAWSTransferServerConfig_forcedestroy(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSTransferServerExists(resourceName, &conf), - testAccCheckAWSRoleExists("aws_iam_role.foo", &roleConf), - resource.TestCheckResourceAttr( - resourceName, "identity_provider_type", "SERVICE_MANAGED"), - resource.TestCheckResourceAttr( - resourceName, "force_destroy", "true"), + resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), + testAccCheckAWSRoleExists("aws_iam_role.test", &roleConf), testAccCheckAWSTransferCreateUser(&conf, &roleConf, rName), testAccCheckAWSTransferCreateSshKey(&conf, rName), ), @@ -242,7 +265,12 @@ func TestAccAWSTransferServer_forcedestroy(t *testing.T) { func TestAccAWSTransferServer_vpcEndpointId(t *testing.T) { var conf transfer.DescribedServer - resourceName := "aws_transfer_server.default" + resourceName := "aws_transfer_server.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + if testAccGetPartition() == "aws-us-gov" { + t.Skip("Transfer Server VPC_ENDPOINT endpoint type is not supported in GovCloud partition") + } resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSTransfer(t) }, @@ -251,11 +279,10 @@ func TestAccAWSTransferServer_vpcEndpointId(t *testing.T) { CheckDestroy: testAccCheckAWSTransferServerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSTransferServerConfig_VpcEndPoint, + Config: testAccAWSTransferServerConfig_VpcEndPoint(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSTransferServerExists(resourceName, &conf), - resource.TestCheckResourceAttr( - resourceName, "endpoint_type", "VPC_ENDPOINT"), + resource.TestCheckResourceAttr(resourceName, "endpoint_type", "VPC_ENDPOINT"), ), }, { @@ -270,7 +297,7 @@ func TestAccAWSTransferServer_vpcEndpointId(t *testing.T) { func TestAccAWSTransferServer_hostKey(t *testing.T) { var conf transfer.DescribedServer - resourceName := "aws_transfer_server.default" + resourceName := "aws_transfer_server.test" hostKey := "test-fixtures/transfer-ssh-rsa-key" resource.ParallelTest(t, resource.TestCase{ @@ -323,23 +350,6 @@ func testAccCheckAWSTransferServerExists(n string, res *transfer.DescribedServer } } -func testAccCheckAWSTransferServerDisappears(conf *transfer.DescribedServer) resource.TestCheckFunc { - return func(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).transferconn - - params := &transfer.DeleteServerInput{ - ServerId: conf.ServerId, - } - - _, err := conn.DeleteServer(params) - if err != nil { - return err - } - - return waitForTransferServerDeletion(conn, *conf.ServerId) - } -} - func testAccCheckAWSTransferServerDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).transferconn @@ -416,60 +426,61 @@ func testAccPreCheckAWSTransfer(t *testing.T) { } } -const testAccAWSTransferServerConfig_basic = ` -resource "aws_transfer_server" "foo" {} +func testAccAWSTransferServerBasicConfig() string { + return ` +resource "aws_transfer_server" "test" {} ` +} -func testAccAWSTransferServerConfig_basicUpdate(rName string) string { +func testAccAWSTransferServerSecurityPolicyConfig(policy string) string { return fmt.Sprintf(` -resource "aws_iam_role" "foo" { - name = "tf-test-transfer-server-iam-role-%[1]s" +resource "aws_transfer_server" "test" { + security_policy_name = %[1]q +} +`, policy) +} + +func testAccAWSTransferServerUpdatedConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_iam_role" "test" { + name = %[1]q assume_role_policy = <