AWS TransferFamily and policy parameters in Terraform

138 Views Asked by At

I am trying to create an SFTP server in AWS TransferFamily using Terraform. I have set the home_directory_type to logical.

According to AWS: "If you are using logical directories—that is, the user's homeDirectoryType is LOGICAL—these policy parameters (HomeBucket, HomeDirectory, and HomeFolder) are not supported"

The problem I have is that I want to create ONE policy for all tenants of the SFTP. In order to do that I need to use some kind of policy variable, for example: ${transfer:UserName} and use it in a policy like this:

"Resource": "arn:aws:s3:::${local.bucket_name}/$${transfer:UserName}/output/*"

This doesn't seem to work (first $ is to escape the variable). Anyone knows how to solve this? Are there other parameters that I can use?

Tried with the variable, did not work. Tried to hardcode the value and it did work. So it seems like the variable is not supported or that I escaped it wrong.

resource "aws_iam_role_policy" "ftp-file-import" {
  name = "${local.name}-ftp-import-policy"
  role = aws_iam_role.ftp-user.name
  policy = <<POLICY
  {
    "Version": "2012-10-17",
    "Statement": [
        {
           "Sid": "AllowListingOfUserFolder",
           "Action": [
               "s3:ListBucket",
               "s3:GetObject",
               "s3:GetBucketLocation"
           ],
           "Effect": "Allow",
           "Resource": [
               "arn:aws:s3:::${local.bucket_name}"
           ]
         },
         {
            "Sid": "HomeDirObjectAccess",
            "Effect": "Allow",
            "Action": [
               "s3:ListBucket",
               "s3:GetObject",
               "s3:GetObjectVersion",
               "s3:GetObjectACL",
               "s3:GetObjectVersion",
               "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::${local.bucket_name}/*"
         },
         {
            "Sid": "OutputFolderAccess",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetObjectVersion",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::${local.bucket_name}/$${transfer:UserName}/output/*"
       }  
     ] 
    }
  POLICY
}
1

There are 1 best solutions below

0
On

There is a much cleaner way of creating a policy in terraform, without the need to use JSON and heredoc syntax. The way you can do this is by using the aws_iam_policy_document data source:

data "aws_iam_policy_document" "ftp-file-import" {
  statement {
    sid = "AllowListingOfUserFolder"
    effect = "Allow"
    actions = [
      "s3:ListBucket",
      "s3:GetObject",
      "s3:GetBucketLocation"      
    ]
    resources = [
      "arn:aws:s3:::${local.bucket_name}"
    ]
  }
  statement {
    sid = "HomeDirObjectAccess"
    effect = "Allow"
    actions = [
      "s3:ListBucket",
      "s3:GetObject",
      "s3:GetObjectVersion",
      "s3:GetObjectACL",
      "s3:GetObjectVersion",
      "s3:GetBucketLocation"      
    ]
    resources = [
      "arn:aws:s3:::${local.bucket_name}/*"
    ]
  }
  statement {
    sid = "OutputFolderAccess"
    effect = "Allow"
    actions = [
      "s3:ListBucket",
      "s3:GetObject",
      "s3:GetObjectVersion",
      "s3:GetObjectVersion",
      "s3:GetBucketLocation"      
    ]
    resources = [
      "arn:aws:s3:::${local.bucket_name}/&{transfer:UserName}/output/*"
    ]
  }
}

resource "aws_iam_policy" "ftp-file-import" {
  policy = data.aws_iam_policy_document.ftp-file-import.json
}

resource "aws_iam_role_policy_attachment" "ftp-file-import" {
  policy_arn = aws_iam_policy.ftp-file-import.arn
  role       = aws_iam_role.ftp-user.name
}

As you can see, instead of using the double $ sign, the documentation says that $ should be used for policy variables:

AWS's IAM policy document syntax allows for replacement of policy variables within a statement using ${...}-style notation, which conflicts with Terraform's interpolation syntax. In order to use AWS policy variables with this data source, use &{...} notation for interpolations that should be processed by AWS rather than by Terraform.

However, even though this should work, I think there might be better ways of doing this, with some examples given in the AWS documentation.