Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,19 @@ Comment in these badges if they apply to the repository.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_accessors_read_write"></a> [accessors\_read\_write](#input\_accessors\_read\_write) | List of accessors that are allowed to read & write. | `list(string)` | `[]` | no |
| <a name="input_access_points"></a> [access\_points](#input\_access\_points) | List of access points to create. | <pre>map(object({<br> posix_user = optional(object({<br> gid = number<br> uid = number<br> secondary_gids = optional(list(number))<br> }))<br><br> root_directory = optional(object({<br> path = string<br><br> creation_info = optional(object({<br> owner_gid = number<br> owner_uid = number<br> permissions = string<br> }))<br> }))<br> }))</pre> | `{}` | no |
| <a name="input_aws_iam_principals"></a> [aws\_iam\_principals](#input\_aws\_iam\_principals) | AWS IAM principals which will be allowed to access the file system via the EFS policy. | `list(string)` | `[]` | no |
| <a name="input_bypass_policy_lockout_safety_check"></a> [bypass\_policy\_lockout\_safety\_check](#input\_bypass\_policy\_lockout\_safety\_check) | A flag to indicate whether to bypass the aws\_efs\_file\_system\_policy lockout safety check. | `bool` | `false` | no |
| <a name="input_enable_customer_managed_kms"></a> [enable\_customer\_managed\_kms](#input\_enable\_customer\_managed\_kms) | If enabled, will create a customer managed KMS key for at-rest encryption. | `bool` | `false` | no |
| <a name="input_enable_enhanced_backups"></a> [enable\_enhanced\_backups](#input\_enable\_enhanced\_backups) | Enable enhanced backups. | `bool` | `false` | no |
| <a name="input_encrypted"></a> [encrypted](#input\_encrypted) | If true, the disk will be encrypted. | `bool` | `true` | no |
| <a name="input_enforce_read_only_default"></a> [enforce\_read\_only\_default](#input\_enforce\_read\_only\_default) | Enforce read-only access to the file system. Identity-based policies can override these default permissions. | `bool` | `false` | no |
| <a name="input_enforce_transit_encryption"></a> [enforce\_transit\_encryption](#input\_enforce\_transit\_encryption) | Enforce in-transit encryption for all clients. | `bool` | `true` | no |
| <a name="input_kms_key_id"></a> [kms\_key\_id](#input\_kms\_key\_id) | The ARN of the AWS KMS to encrypt the file system. Defaults to the AWS managed KMS key. | `string` | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | The name of the file system. | `string` | n/a | yes |
| <a name="input_performance_mode"></a> [performance\_mode](#input\_performance\_mode) | The file system performance mode. Can be either `generalPurpose` or `maxIO`. | `string` | `"generalPurpose"` | no |
| <a name="input_prevent_anonymous_access"></a> [prevent\_anonymous\_access](#input\_prevent\_anonymous\_access) | Prevent anonymous access to the file system. | `bool` | `false` | no |
| <a name="input_prevent_root_access_default"></a> [prevent\_root\_access\_default](#input\_prevent\_root\_access\_default) | Prevent root access to the file system. Identity-based policies can override these default permissions. | `bool` | `false` | no |
| <a name="input_private_subnets"></a> [private\_subnets](#input\_private\_subnets) | A list of private subnets inside the VPC. | `list(string)` | n/a | yes |
| <a name="input_provisioned_throughput_in_mibps"></a> [provisioned\_throughput\_in\_mibps](#input\_provisioned\_throughput\_in\_mibps) | The throughput, measured in MiB/s, that you want to provision for the file system. | `number` | `0` | no |
| <a name="input_security_groups"></a> [security\_groups](#input\_security\_groups) | A list of security group IDs to associate with the file system. | `list(string)` | n/a | yes |
Expand Down Expand Up @@ -78,12 +85,12 @@ Comment in these badges if they apply to the repository.

## Resources

- resource.aws_efs_file_system.main (main.tf#1)
- resource.aws_efs_file_system_policy.main (main.tf#44)
- resource.aws_efs_mount_target.main (main.tf#37)
- resource.random_uuid.main (main.tf#52)
- data source.aws_caller_identity.current (data.tf#1)
- data source.aws_iam_policy_document.main (data.tf#3)
- resource.aws_efs_access_point.main (main.tf#44)
- resource.aws_efs_file_system.main (main.tf#3)
- resource.aws_efs_file_system_policy.main (main.tf#37)
- resource.aws_efs_mount_target.main (main.tf#28)
- resource.random_uuid.main (main.tf#1)
- data source.aws_iam_policy_document.main (data.tf#1)

# Examples
### Basic Example
Expand Down
66 changes: 44 additions & 22 deletions data.tf
Original file line number Diff line number Diff line change
@@ -1,28 +1,50 @@
data "aws_caller_identity" "current" {}

data "aws_iam_policy_document" "main" {
statement {
sid = "Allow Access to EFS"
effect = "Allow"
resources = [aws_efs_file_system.main.arn]

actions = [
"elasticfilesystem:ClientMount",
"elasticfilesystem:ClientWrite",
]

condition {
test = "Bool"
variable = "aws:SecureTransport"
values = ["true"]
dynamic "statement" {
for_each = [true]

content {
sid = "AccessRules"
resources = [aws_efs_file_system.main.arn]
effect = "Allow"

principals {
type = "AWS"
identifiers = var.aws_iam_principals
}

actions = compact([
!var.prevent_root_access_default ? "elasticfilesystem:ClientRootAccess" : null,
!var.enforce_read_only_default ? "elasticfilesystem:ClientWrite" : null,
!var.prevent_anonymous_access ? "elasticfilesystem:ClientMount" : null,
])

condition {
test = "Bool"
variable = "elasticfilesystem:AccessedViaMountTarget"
values = ["true"]
}
}
}

dynamic "statement" {
for_each = var.enforce_transit_encryption ? [true] : []

content {
sid = "EnforceInTransitEncryption"
resources = [aws_efs_file_system.main.arn]
effect = "Deny"
actions = ["*"]

principals {
type = "AWS"
identifiers = ["*"]
}

principals {
type = "AWS"
identifiers = concat(
["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"],
var.accessors_read_write
)
condition {
test = "Bool"
variable = "aws:SecureTransport"
values = ["false"]
}
}
}
}
86 changes: 58 additions & 28 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
resource "aws_efs_file_system" "main" {
resource "random_uuid" "main" {}

# Creation token
resource "aws_efs_file_system" "main" {
creation_token = random_uuid.main.result

# Encryption
encrypted = var.encrypted

# KMS
kms_key_id = module.kms.key_arn
encrypted = var.encrypted
kms_key_id = var.enable_customer_managed_kms ? module.kms[0].key_arn : var.kms_key_id

# Performance Mode
performance_mode = var.performance_mode

# Throughput mode
throughput_mode = var.throughput_mode

# Throughput provision
# Performance
performance_mode = var.performance_mode
throughput_mode = var.throughput_mode
provisioned_throughput_in_mibps = var.provisioned_throughput_in_mibps

lifecycle_policy {
Expand All @@ -26,30 +20,64 @@ resource "aws_efs_file_system" "main" {
transition_to_primary_storage_class = var.transition_to_primary_storage_class
}

tags = merge(
var.tags,
{
"Name" = var.name
}
)
tags = merge(var.tags, {
"Name" = var.name
})
}

resource "aws_efs_mount_target" "main" {
count = length(var.private_subnets)
file_system_id = aws_efs_file_system.main.id
count = length(var.private_subnets)

file_system_id = aws_efs_file_system.main.id

security_groups = var.security_groups
subnet_id = var.private_subnets[count.index]
}

resource "aws_efs_file_system_policy" "main" {
file_system_id = aws_efs_file_system.main.id

policy = data.aws_iam_policy_document.main.json
bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check

policy = data.aws_iam_policy_document.main.json
}

resource "random_uuid" "main" {}
resource "aws_efs_access_point" "main" {
for_each = var.access_points

file_system_id = aws_efs_file_system.main.id

dynamic "posix_user" {
for_each = each.value.posix_user != null ? [each.value.posix_user] : []

content {
uid = posix_user.value.uid
gid = posix_user.value.gid
secondary_gids = posix_user.value.secondary_gids
}
}

dynamic "root_directory" {
for_each = each.value.root_directory != null ? [each.value.root_directory] : []

content {
path = root_directory.value.path

dynamic "creation_info" {
for_each = root_directory.value.creation_info != null ? [root_directory.value.creation_info] : []

content {
owner_uid = creation_info.value.owner_uid
owner_gid = creation_info.value.owner_gid
permissions = creation_info.value.permissions
}
}
}
}

tags = merge(var.tags, {
"Name" = "${var.name}-${each.key}"
})
}

module "backup" {
count = var.enable_enhanced_backups ? 1 : 0
Expand All @@ -60,16 +88,18 @@ module "backup" {
vault_name = var.name
backup_name = var.name

resources = [
aws_efs_file_system.main.arn
]
service = "efs"
resources = [aws_efs_file_system.main.arn]

service = "efs"
tags = var.tags
}

module "kms" {
count = var.enable_customer_managed_kms ? 1 : 0

source = "geekcell/kms/aws"
version = ">= 1.0.0, < 2.0.0"

alias = format("alias/efs/%s", var.name)
tags = var.tags
}
62 changes: 60 additions & 2 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ variable "encrypted" {
type = bool
}

variable "kms_key_id" {
description = "The ARN of the AWS KMS to encrypt the file system. Defaults to the AWS managed KMS key."
default = null
type = string
}

variable "enable_customer_managed_kms" {
description = "If enabled, will create a customer managed KMS key for at-rest encryption."
default = false
type = bool
}

variable "name" {
description = "The name of the file system."
type = string
Expand Down Expand Up @@ -69,8 +81,54 @@ variable "transition_to_primary_storage_class" {
type = string
}

variable "accessors_read_write" {
variable "access_points" {
default = {}
description = "List of access points to create."
type = map(object({
posix_user = optional(object({
gid = number
uid = number
secondary_gids = optional(list(number))
}))

root_directory = optional(object({
path = string

creation_info = optional(object({
owner_gid = number
owner_uid = number
permissions = string
}))
}))
}))
}

variable "aws_iam_principals" {
description = "AWS IAM principals which will be allowed to access the file system via the EFS policy."
default = []
description = "List of accessors that are allowed to read & write."
type = list(string)
}

variable "prevent_root_access_default" {
description = "Prevent root access to the file system. Identity-based policies can override these default permissions."
default = false
type = bool
}

variable "enforce_read_only_default" {
description = "Enforce read-only access to the file system. Identity-based policies can override these default permissions."
default = false
type = bool
}

variable "prevent_anonymous_access" {
description = "Prevent anonymous access to the file system."
default = false
type = bool
}

variable "enforce_transit_encryption" {
description = "Enforce in-transit encryption for all clients."
default = true
type = bool
}