Skip to content

File System

Progress checklist

The S3FILES
Amazon S3 Files — a service that exposes an S3 bucket as a shared NFS file system. Supports EC2, EKS, ECS (Fargate), and Lambda. Uses the CLI namespace `aws s3files` and mount type `-t s3files`. Read APIs are `list-*` and `get-*` (for example `list-file-systems`, `get-file-system`), not `describe-*`.
file system links your bucket to a mountable NFS endpoint. Before creating it you must create the IAM role S3 Files assumes to read and write your bucket — both steps are on this page.

  1. Confirm base exports. Required

    Re-run these in your current shell. Replace my-s3-files-bucket with the exact name of the bucket you created in the Bucket step — this value is embedded in the IAM policy resource ARNs written in steps 2–3. Using the wrong name here is the most common cause of the file system getting stuck in creating.

    Terminal window
    export AWS_REGION=ap-southeast-6
    export BUCKET=my-s3-files-bucket # ← replace with your real bucket name
    export BUCKET_ARN=arn:aws:s3:::${BUCKET}
    export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
    echo "Account: $ACCOUNT_ID Region: $AWS_REGION Bucket: $BUCKET ARN: $BUCKET_ARN"

    Confirm the echo output shows your real bucket name (not the placeholder) before continuing.

    If the bucket does not exist yet, complete Bucket first.

  2. Create the IAM role S3 Files assumes (trust policy). Required

    This role allows elasticfilesystem.amazonaws.com to assume it, scoped to this account and region. The heredoc uses unquoted <<EOF so the shell expands ${ACCOUNT_ID} and ${AWS_REGION} — do not use <<'EOF'.

    fs-trust-policy.json
    cat > /tmp/fs-trust-policy.json <<EOF
    {
    "Version": "2012-10-17",
    "Statement": [{
    "Sid": "AllowS3FilesAssumeRole",
    "Effect": "Allow",
    "Principal": { "Service": "elasticfilesystem.amazonaws.com" },
    "Action": "sts:AssumeRole",
    "Condition": {
    "StringEquals": { "aws:SourceAccount": "${ACCOUNT_ID}" },
    "ArnLike": {
    "aws:SourceArn": "arn:aws:s3files:${AWS_REGION}:${ACCOUNT_ID}:file-system/*"
    }
    }
    }]
    }
    EOF
    Terminal window
    aws iam create-role \
    --role-name s3files-filesystem-role \
    --assume-role-policy-document file:///tmp/fs-trust-policy.json

    Verify the trust policy expanded correctly — you must see your account ID digits and region code, not literal ${ACCOUNT_ID}:

    Terminal window
    aws iam get-role \
    --role-name s3files-filesystem-role \
    --query 'Role.AssumeRolePolicyDocument' \
    --output json
  3. Attach the file system inline policy (S3, KMS, EventBridge). Required

    This grants S3 Files read/write access to the bucket, optional SSE-KMS key use, and EventBridge sync rule management, following the AWS prerequisites for S3 Files.

    fs-inline-policy.json
    cat > /tmp/fs-inline-policy.json <<EOF
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "S3BucketPermissions",
    "Effect": "Allow",
    "Action": ["s3:ListBucket", "s3:ListBucketVersions"],
    "Resource": "${BUCKET_ARN}",
    "Condition": { "StringEquals": { "aws:ResourceAccount": "${ACCOUNT_ID}" } }
    },
    {
    "Sid": "S3ObjectPermissions",
    "Effect": "Allow",
    "Action": ["s3:AbortMultipartUpload", "s3:DeleteObject*", "s3:GetObject*", "s3:HeadObject", "s3:List*", "s3:PutObject*"],
    "Resource": "${BUCKET_ARN}/*",
    "Condition": { "StringEquals": { "aws:ResourceAccount": "${ACCOUNT_ID}" } }
    },
    {
    "Sid": "UseKmsKeyWithS3Files",
    "Effect": "Allow",
    "Action": ["kms:GenerateDataKey", "kms:Encrypt", "kms:Decrypt", "kms:ReEncryptFrom", "kms:ReEncryptTo"],
    "Condition": {
    "StringLike": {
    "kms:ViaService": "s3.${AWS_REGION}.amazonaws.com",
    "kms:EncryptionContext:aws:s3:arn": ["${BUCKET_ARN}", "${BUCKET_ARN}/*"]
    }
    },
    "Resource": "arn:aws:kms:${AWS_REGION}:${ACCOUNT_ID}:*"
    },
    {
    "Sid": "EventBridgeManage",
    "Effect": "Allow",
    "Action": ["events:DeleteRule", "events:DisableRule", "events:EnableRule", "events:PutRule", "events:PutTargets", "events:RemoveTargets"],
    "Condition": { "StringEquals": { "events:ManagedBy": "elasticfilesystem.amazonaws.com" } },
    "Resource": ["arn:aws:events:*:*:rule/DO-NOT-DELETE-S3-Files*"]
    },
    {
    "Sid": "EventBridgeRead",
    "Effect": "Allow",
    "Action": ["events:DescribeRule", "events:ListRuleNamesByTarget", "events:ListRules", "events:ListTargetsByRule"],
    "Resource": ["arn:aws:events:*:*:rule/*"]
    }
    ]
    }
    EOF
    Terminal window
    aws iam put-role-policy \
    --role-name s3files-filesystem-role \
    --policy-name S3FilesFileSystemPolicy \
    --policy-document file:///tmp/fs-inline-policy.json
  4. Verify the file system role is ready. Required

    Terminal window
    aws iam get-role-policy \
    --role-name s3files-filesystem-role \
    --policy-name S3FilesFileSystemPolicy \
    --query 'PolicyDocument.Statement[0:2]' \
    --output json

    Check that both Resource values contain your real bucket name, not my-s3-files-bucket:

    Terminal window
    aws iam get-role-policy \
    --role-name s3files-filesystem-role \
    --policy-name S3FilesFileSystemPolicy \
    --query 'PolicyDocument.Statement[*].Resource' \
    --output text

    If you see my-s3-files-bucket in the output, stop. Re-run step 1 with the correct BUCKET= value, re-run step 3 (put-role-policy), then re-run this verification before continuing.

  5. Set the file system role ARN. Required

    Terminal window
    export FS_ROLE_ARN=arn:aws:iam::${ACCOUNT_ID}:role/s3files-filesystem-role
    echo "FS_ROLE_ARN=$FS_ROLE_ARN"
  6. Create the file system. Required

    Terminal window
    aws s3files create-file-system \
    --region $AWS_REGION \
    --bucket $BUCKET_ARN \
    --role-arn $FS_ROLE_ARN

    The response is JSON. Note the fileSystemId value — it starts with fs-.

  7. Export the file system ID.

    Terminal window
    export FS_ID=$(aws s3files list-file-systems \
    --region $AWS_REGION \
    --bucket $BUCKET_ARN \
    --query 'fileSystems[0].fileSystemId' \
    --output text)
    echo "File system: $FS_ID"
  8. Wait for the file system to become available.

    File system creation typically completes within one to two minutes. Re-run until the output is available:

    Terminal window
    aws s3files get-file-system \
    --region $AWS_REGION \
    --file-system-id $FS_ID \
    --query 'status' \
    --output text

    Once the output is available, the console’s Synchronization configuration “Unknown Error” and the “no mount targets” warning both clear — no action required.

Continue to Mount Targets to create network endpoints in each Availability Zone.