Skip to content

Commit

Permalink
Merge pull request #22039 from nij4t/lamda_identity_provider
Browse files Browse the repository at this point in the history
r/transfer: add lambda identity provider support
  • Loading branch information
ewbankkit authored Dec 3, 2021
2 parents adb46fe + 8a79281 commit 340fa9d
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .changelog/22039.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_transfer_server: Add `function` argument in support of custom identity providers
```
6 changes: 6 additions & 0 deletions .github/workflows/terraform_provider.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ jobs:
if [ "${pkg}" = "" ]; then
continue
fi
if [[ "${pkg}" == */test-fixtures ]]; then
continue
fi
while read file; do
if [ "${file}" = "" ]; then
continue
Expand All @@ -252,6 +255,9 @@ jobs:
if [ "${pkg}" = "internal/sweep" ]; then
continue
fi
if [[ "${pkg}" == */test-fixtures ]]; then
continue
fi
go test -run ^Test[^A][^c][^c] "github.com/hashicorp/terraform-provider-aws/${pkg}"
done </tmp/dep_pkgs
Expand Down
5 changes: 5 additions & 0 deletions .tflint.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@ plugin "aws" {
version = "0.7.1"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}

# https://github.com/terraform-linters/tflint-ruleset-aws/issues/206
rule "aws_transfer_server_invalid_identity_provider_type" {
enabled = false
}
25 changes: 24 additions & 1 deletion internal/service/transfer/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ func ResourceServer() *schema.Resource {
Default: false,
},

"function": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.ValidARN,
},

"host_key": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -229,6 +235,14 @@ func resourceServerCreate(d *schema.ResourceData, meta interface{}) error {
input.EndpointType = aws.String(v.(string))
}

if v, ok := d.GetOk("function"); ok {
if input.IdentityProviderDetails == nil {
input.IdentityProviderDetails = &transfer.IdentityProviderDetails{}
}

input.IdentityProviderDetails.Function = aws.String(v.(string))
}

if v, ok := d.GetOk("host_key"); ok {
input.HostKey = aws.String(v.(string))
}
Expand Down Expand Up @@ -359,6 +373,11 @@ func resourceServerRead(d *schema.ResourceData, meta interface{}) error {
d.Set("endpoint_details", nil)
}
d.Set("endpoint_type", output.EndpointType)
if output.IdentityProviderDetails != nil {
d.Set("function", output.IdentityProviderDetails.Function)
} else {
d.Set("function", "")
}
d.Set("host_key_fingerprint", output.HostKeyFingerprint)
d.Set("identity_provider_type", output.IdentityProviderType)
if output.IdentityProviderDetails != nil {
Expand Down Expand Up @@ -508,13 +527,17 @@ func resourceServerUpdate(d *schema.ResourceData, meta interface{}) error {
}
}

if d.HasChanges("directory_id", "invocation_role", "url") {
if d.HasChanges("directory_id", "function", "invocation_role", "url") {
identityProviderDetails := &transfer.IdentityProviderDetails{}

if attr, ok := d.GetOk("directory_id"); ok {
identityProviderDetails.DirectoryId = aws.String(attr.(string))
}

if attr, ok := d.GetOk("function"); ok {
identityProviderDetails.Function = aws.String(attr.(string))
}

if attr, ok := d.GetOk("invocation_role"); ok {
identityProviderDetails.InvocationRole = aws.String(attr.(string))
}
Expand Down
54 changes: 54 additions & 0 deletions internal/service/transfer/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func testAccServer_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "endpoint_details.#", "0"),
resource.TestCheckResourceAttr(resourceName, "endpoint_type", "PUBLIC"),
resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"),
resource.TestCheckResourceAttr(resourceName, "function", ""),
resource.TestCheckNoResourceAttr(resourceName, "host_key"),
resource.TestCheckResourceAttrSet(resourceName, "host_key_fingerprint"),
resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"),
Expand Down Expand Up @@ -79,6 +80,7 @@ func testAccServer_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "endpoint_details.#", "0"),
resource.TestCheckResourceAttr(resourceName, "endpoint_type", "PUBLIC"),
resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"),
resource.TestCheckResourceAttr(resourceName, "function", ""),
resource.TestCheckNoResourceAttr(resourceName, "host_key"),
resource.TestCheckResourceAttrSet(resourceName, "host_key_fingerprint"),
resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"),
Expand Down Expand Up @@ -910,6 +912,35 @@ func testAccServer_vpcEndpointID(t *testing.T) {
})
}

func testAccServer_lambdaFunction(t *testing.T) {
var conf transfer.DescribedServer
resourceName := "aws_transfer_server.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckAPIGatewayTypeEDGE(t); testAccPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, transfer.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckServerDestroy,
Steps: []resource.TestStep{
{
Config: testAccServerLambdaFunctionIdentityProviderTypeConfig(rName, false),
Check: resource.ComposeTestCheckFunc(
testAccCheckServerExists(resourceName, &conf),
resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "AWS_LAMBDA"),
resource.TestCheckResourceAttrPair(resourceName, "function", "aws_lambda_function.test", "arn"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"force_destroy"},
},
},
})
}

func testAccCheckServerExists(n string, v *transfer.DescribedServer) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down Expand Up @@ -1546,3 +1577,26 @@ resource "aws_transfer_server" "test" {
}
`, rName))
}

func testAccServerLambdaFunctionIdentityProviderTypeConfig(rName string, forceDestroy bool) string {
return acctest.ConfigCompose(
acctest.ConfigLambdaBase(rName, rName, rName),
testAccServerBaseLoggingRoleConfig(rName+"-logging"),
fmt.Sprintf(`
resource "aws_lambda_function" "test" {
filename = "test-fixtures/lambdatest.zip"
function_name = %[1]q
role = aws_iam_role.iam_for_lambda.arn
handler = "index.handler"
runtime = "nodejs14.x"
}
resource "aws_transfer_server" "test" {
identity_provider_type = "AWS_LAMBDA"
function = aws_lambda_function.test.arn
logging_role = aws_iam_role.test.arn
force_destroy = %[2]t
}
`, rName, forceDestroy))
}
Binary file not shown.
1 change: 1 addition & 0 deletions internal/service/transfer/transfer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func TestAccTransfer_serial(t *testing.T) {
"Domain": testAccServer_domain,
"ForceDestroy": testAccServer_forceDestroy,
"HostKey": testAccServer_hostKey,
"LambdaFunction": testAccServer_lambdaFunction,
"Protocols": testAccServer_protocols,
"SecurityPolicy": testAccServer_securityPolicy,
"UpdateEndpointTypePublicToVPC": testAccServer_updateEndpointType_publicToVPC,
Expand Down
12 changes: 11 additions & 1 deletion website/docs/r/transfer_server.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ resource "aws_transfer_server" "example" {
}
```

### AWS Lambda authentication

```terraform
resource "aws_transfer_server" "example" {
identity_provider_type = "AWS_LAMBDA"
function = aws_lambda_identity_provider.example.arn
}
```

### Protocols

```terraform
Expand Down Expand Up @@ -89,8 +98,9 @@ The following arguments are supported:
* `invocation_role` - (Optional) Amazon Resource Name (ARN) of the IAM role used to authenticate the user account with an `identity_provider_type` of `API_GATEWAY`.
* `host_key` - (Optional) RSA private key (e.g., as generated by the `ssh-keygen -N "" -m PEM -f my-new-server-key` command).
* `url` - (Optional) - URL of the service endpoint used to authenticate users with an `identity_provider_type` of `API_GATEWAY`.
* `identity_provider_type` - (Optional) The mode of authentication enabled for this service. The default value is `SERVICE_MANAGED`, which allows you to store and access SFTP user credentials within the service. `API_GATEWAY` indicates that user authentication requires a call to an API Gateway endpoint URL provided by you to integrate an identity provider of your choice. Using `AWS_DIRECTORY_SERVICE` will allow for authentication against AWS Managed Active Directory or Microsoft Active Directory in your on-premises environment, or in AWS using AD Connectors.
* `identity_provider_type` - (Optional) The mode of authentication enabled for this service. The default value is `SERVICE_MANAGED`, which allows you to store and access SFTP user credentials within the service. `API_GATEWAY` indicates that user authentication requires a call to an API Gateway endpoint URL provided by you to integrate an identity provider of your choice. Using `AWS_DIRECTORY_SERVICE` will allow for authentication against AWS Managed Active Directory or Microsoft Active Directory in your on-premises environment, or in AWS using AD Connectors. Use the `AWS_LAMBDA` value to directly use a Lambda function as your identity provider. If you choose this value, you must specify the ARN for the lambda function in the `function` argument.
* `directory_id` - (Optional) The directory service ID of the directory service you want to connect to with an `identity_provider_type` of `AWS_DIRECTORY_SERVICE`.
* `function` - (Optional) The ARN for a lambda function to use for the Identity provider.
* `logging_role` - (Optional) Amazon Resource Name (ARN) of an IAM role that allows the service to write your SFTP users’ activity to your Amazon CloudWatch logs for monitoring and auditing purposes.
* `force_destroy` - (Optional) A boolean that indicates all users associated with the server should be deleted so that the Server can be destroyed without error. The default value is `false`. This option only applies to servers configured with a `SERVICE_MANAGED` `identity_provider_type`.
* `security_policy_name` - (Optional) Specifies the name of the security policy that is attached to the server. Possible values are `TransferSecurityPolicy-2018-11`, `TransferSecurityPolicy-2020-06`, and `TransferSecurityPolicy-FIPS-2020-06`. Default value is: `TransferSecurityPolicy-2018-11`.
Expand Down

0 comments on commit 340fa9d

Please sign in to comment.