diff --git a/modules/aws/transfer_family/README.md b/modules/aws/transfer_family/README.md index 47f8784f..9fa5748e 100755 --- a/modules/aws/transfer_family/README.md +++ b/modules/aws/transfer_family/README.md @@ -121,6 +121,8 @@ _For more examples, please refer to the [Documentation](https://github.com/zachr | [aws_transfer_server.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/transfer_server) | resource | | [aws_transfer_ssh_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/transfer_ssh_key) | resource | | [aws_transfer_user.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/transfer_user) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | ## Inputs @@ -130,7 +132,7 @@ _For more examples, please refer to the [Documentation](https://github.com/zachr | [as2\_transports](#input\_as2\_transports) | (Optional) The transport method for AS2 messages. Valid values are HTTP. | `list(string)` | `null` | no | | [certificate](#input\_certificate) | (Optional) The ARN of the AWS Certificate Manager certificate to use with the server | `string` | `null` | no | | [directory\_id](#input\_directory\_id) | (Optional) The ID of the AWS Directory Service directory that you want to associate with the server | `string` | `null` | no | -| [endpoint\_type](#input\_endpoint\_type) | (Optional) The type of endpoint that you want your server to use. Valid values are VPC and PUBLIC | `string` | `"PUBLIC"` | no | +| [endpoint\_type](#input\_endpoint\_type) | (Optional) The type of endpoint that you want your server to use. Valid values are PUBLIC, VPC, and VPC\_ENDPOINT. Default value is PUBLIC. | `string` | `"PUBLIC"` | no | | [function](#input\_function) | (Optional) The ARN of the AWS Lambda function that is invoked for user authentication | `string` | `null` | no | | [host\_key](#input\_host\_key) | (Optional) The RSA, ECDSA, or ED25519 private key. This must be created ahead of time. | `string` | `null` | no | | [identity\_provider\_type](#input\_identity\_provider\_type) | (Optional) The mode of authentication enabled for this service. Valid values are SERVICE\_MANAGED or API\_GATEWAY | `string` | `"SERVICE_MANAGED"` | no | @@ -150,7 +152,7 @@ _For more examples, please refer to the [Documentation](https://github.com/zachr | [tags](#input\_tags) | (Optional) Key-value mapping of resource tags | `map(string)` |
{
"terraform": "true"
}
| no | | [tls\_session\_resumption\_mode](#input\_tls\_session\_resumption\_mode) | (Optional) Specifies the mode of the TLS session resumption. Valid values are: DISABLED, ENABLED, and ENFORCED. | `string` | `null` | no | | [url](#input\_url) | (Optional) The URL of the file transfer protocol endpoint that is used to authentication users through an API\_GATEWAY. | `string` | `null` | no | -| [users](#input\_users) | (Optional) A map of user names and their configuration |
map(object({
home_directory = optional(string) # Cannot be set if home_directory_type is set to "LOGICAL".
home_directory_type = optional(string, "LOGICAL") # Default is "LOGICAL"
policy = optional(string) # Set for a custom session policy see https://docs.aws.amazon.com/transfer/latest/userguide/requirements-roles.html#session-policy for more information
public_key = optional(string) # The public key portion of an SSH key pair
username = string
}))
| `{}` | no | +| [users](#input\_users) | (Optional) A map of user names and their configuration |
map(object({
home_directory = optional(string) # The landing directory for a user. Cannot be set if home_directory_type is set to "LOGICAL".
home_directory_type = optional(string, "LOGICAL") # The type of landing directory. Valid values are `PATH` and `LOGICAL`. Defaults to `LOGICAL`.
policy = optional(string) # Set for a custom session policy see https://docs.aws.amazon.com/transfer/latest/userguide/requirements-roles.html#session-policy for more information
public_key = optional(string) # The public key portion of an SSH key pair. See https://docs.aws.amazon.com/transfer/latest/userguide/key-management.html for supported key algorithms.
username = string # The username of the user.
}))
| `{}` | no | | [vpc\_endpoint\_id](#input\_vpc\_endpoint\_id) | (Optional) The ID of the VPC endpoint. This property can only be used when endpoint\_type is set to VPC. | `string` | `null` | no | | [vpc\_id](#input\_vpc\_id) | (Optional) The ID of the VPC that is used for the transfer server. This property can only be used when endpoint\_type is set to VPC. | `string` | `null` | no | @@ -158,6 +160,7 @@ _For more examples, please refer to the [Documentation](https://github.com/zachr | Name | Description | |------|-------------| +| [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | The ARN of the S3 bucket | | [server\_arn](#output\_server\_arn) | The ARN of the transfer family server | | [server\_endpoint](#output\_server\_endpoint) | The endpoint of the transfer family server | | [server\_host\_key\_fingerprint](#output\_server\_host\_key\_fingerprint) | The RSA private key fingerprint of the transfer family server | diff --git a/modules/aws/transfer_family/main.tf b/modules/aws/transfer_family/main.tf index be883f41..a3eb9df9 100755 --- a/modules/aws/transfer_family/main.tf +++ b/modules/aws/transfer_family/main.tf @@ -15,10 +15,55 @@ terraform { # Data Sources ########################### +data "aws_caller_identity" "current" {} +data "aws_region" "current" {} ########################### # Locals ########################### +locals { + # The default session policy used by the transfer family server and each user. This policy allows each user access to ONLY their home directory. + default_session_policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Sid = "AllowListingOfUserFolder", + Action = [ + "s3:ListBucket", + "s3:GetBucketLocation" + ], + Effect = "Allow", + Resource = [ + "arn:aws:s3:::$${Transfer:HomeBucket}" + ] + Condition = { + StringLike = { + "s3:prefix" : [ + "$${Transfer:HomeDirectory}/*", + "$${Transfer:HomeDirectory}" + ] + } + } + }, + { + Sid = "HomeDirObjectAccess", + Action = [ + "s3:DeleteObject", + "s3:DeleteObjectVersion", + "s3:GetObject", + "s3:GetObjectACL", + "s3:GetObjectVersion", + "s3:PutObject", + "s3:PutObjectACL" + ], + Effect = "Allow", + Resource = [ + "arn:aws:s3:::$${Transfer:HomeBucket}/$${Transfer:HomeDirectory}/*" + ] + } + ] + }) +} ########################### # Module Configuration @@ -107,11 +152,11 @@ module "transfer_family_iam_role_policy" { { Sid = "HomeDirObjectAccess", Action = [ + "s3:DeleteObject", + "s3:DeleteObjectVersion", "s3:GetObject", "s3:GetObjectACL", "s3:GetObjectVersion", - "s3:DeleteObject", - "s3:DeleteObjectVersion", "s3:PutObject", "s3:PutObjectACL" ], @@ -131,6 +176,14 @@ module "transfer_family_iam_role" { Statement = [ { Action = "sts:AssumeRole", + Condition = { + StringEquals = { + "aws:SourceAccount" : "${data.aws_caller_identity.current.account_id}" + }, + ArnLike = { + "aws:SourceArn" : "arn:aws:transfer:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:user/*" + } + }, Effect = "Allow", Principal = { Service = "transfer.amazonaws.com" @@ -153,14 +206,14 @@ resource "aws_transfer_user" "this" { home_directory = each.value.home_directory home_directory_type = each.value.home_directory_type - policy = each.value.policy + policy = each.value.home_directory_type == "LOGICAL" ? null : (each.value.policy == null ? local.default_session_policy : each.value.policy) role = module.transfer_family_iam_role.arn server_id = aws_transfer_server.this.id tags = var.tags user_name = each.value.username dynamic "home_directory_mappings" { - # Disables the dynamic block of home_directory_mappings if home_directory_type is not "LOGICAL". + # Disables the dynamic block of home_directory_mappings if home_directory_type is not `LOGICAL`. for_each = each.value.home_directory_type == "LOGICAL" ? [1] : [] content { entry = "/" diff --git a/modules/aws/transfer_family/outputs.tf b/modules/aws/transfer_family/outputs.tf index 6e9f61c9..9808f1a0 100755 --- a/modules/aws/transfer_family/outputs.tf +++ b/modules/aws/transfer_family/outputs.tf @@ -2,6 +2,11 @@ # Resource Outputs ########################### +output "s3_bucket_arn" { + description = "The ARN of the S3 bucket" + value = module.bucket.s3_bucket_arn +} + output "server_arn" { description = "The ARN of the transfer family server" value = aws_transfer_server.this.arn diff --git a/modules/aws/transfer_family/variables.tf b/modules/aws/transfer_family/variables.tf index f86ca55a..e5ff4998 100755 --- a/modules/aws/transfer_family/variables.tf +++ b/modules/aws/transfer_family/variables.tf @@ -35,9 +35,13 @@ variable "directory_id" { } variable "endpoint_type" { - description = "(Optional) The type of endpoint that you want your server to use. Valid values are VPC and PUBLIC" + description = "(Optional) The type of endpoint that you want your server to use. Valid values are PUBLIC, VPC, and VPC_ENDPOINT. Default value is PUBLIC." type = string default = "PUBLIC" + validation { + condition = can(regex("^(PUBLIC|VPC|VPC_ENDPOINT)$", var.endpoint_type)) + error_message = "The value of endpoint_type must be either PUBLIC, VPC, or VPC_ENDPOINT." + } } variable "function" { @@ -222,11 +226,11 @@ variable "lifecycle_rules" { variable "users" { description = "(Optional) A map of user names and their configuration" type = map(object({ - home_directory = optional(string) # Cannot be set if home_directory_type is set to "LOGICAL". - home_directory_type = optional(string, "LOGICAL") # Default is "LOGICAL" + home_directory = optional(string) # The landing directory for a user. Cannot be set if home_directory_type is set to "LOGICAL". + home_directory_type = optional(string, "LOGICAL") # The type of landing directory. Valid values are `PATH` and `LOGICAL`. Defaults to `LOGICAL`. policy = optional(string) # Set for a custom session policy see https://docs.aws.amazon.com/transfer/latest/userguide/requirements-roles.html#session-policy for more information - public_key = optional(string) # The public key portion of an SSH key pair - username = string + public_key = optional(string) # The public key portion of an SSH key pair. See https://docs.aws.amazon.com/transfer/latest/userguide/key-management.html for supported key algorithms. + username = string # The username of the user. })) default = {} }