Skip to content

Commit

Permalink
feat: Initial release of efs module 🎉
Browse files Browse the repository at this point in the history
  • Loading branch information
bryantbiggs committed Oct 24, 2022
1 parent bc7ad90 commit b69550c
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 20 deletions.
92 changes: 90 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,93 @@ See [`examples`](https://github.com/terraform-aws-modules/terraform-aws-efs/tree
module "efs" {
source = "terraform-aws-modules/efs/aws"
# File system
name = "example"
creation_token = "example-token"
encrypted = true
kms_key_arn = "arn:aws:kms:eu-west-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
performance_mode = "maxIO"
throughput_mode = "provisioned"
provisioned_throughput_in_mibps = 256
lifecycle_policy = {
transition_to_ia = "AFTER_30_DAYS"
}
# File system policy
attach_policy = true
bypass_policy_lockout_safety_check = false
policy_statements = [
{
sid = "Example"
actions = ["elasticfilesystem:ClientMount"]
principals = [
{
type = "AWS"
identifiers = ["arn:aws:iam::111122223333:role/EfsReadOnly"]
}
]
}
]
# Mount targets / security group
mount_targets = {
"eu-west-1a" = {
subnet_id = "subnet-abcde012"
}
"eu-west-1b" = {
subnet_id = "subnet-bcde012a"
}
"eu-west-1c" = {
subnet_id = "subnet-fghi345a"
}
}
security_group_description = "Example EFS security group"
security_group_vpc_id = "vpc-1234556abcdef"
security_group_rules = {
vpc = {
# relying on the defaults provdied for EFS/NFS (2049/TCP + ingress)
description = "NFS ingress from VPC private subnets"
cidr_blocks = ["10.99.3.0/24", "10.99.4.0/24", "10.99.5.0/24"]
}
}
# Access point(s)
access_points = {
posix_example = {
name = "posix-example"
posix_user = {
gid = 1001
uid = 1001
secondary_gids = [1002]
}
tags = {
Additionl = "yes"
}
}
root_example = {
root_directory = {
path = "/example"
creation_info = {
owner_gid = 1001
owner_uid = 1001
permissions = "755"
}
}
}
}
# Backup policy
enable_backup_policy = true
# Replication configuration
create_replication_configuration = true
replication_configuration_destination = {
region = "eu-west-2"
}
tags = {
Terraform = "true"
Environment = "dev"
Expand Down Expand Up @@ -69,12 +156,13 @@ No modules.
| <a name="input_creation_token"></a> [creation\_token](#input\_creation\_token) | A unique name (a maximum of 64 characters are allowed) used as reference when creating the Elastic File System to ensure idempotent file system creation. By default generated by Terraform | `string` | `null` | no |
| <a name="input_enable_backup_policy"></a> [enable\_backup\_policy](#input\_enable\_backup\_policy) | Determines whether a backup policy is `ENABLED` or `DISABLED` | `bool` | `true` | no |
| <a name="input_encrypted"></a> [encrypted](#input\_encrypted) | If `true`, the disk will be encrypted | `bool` | `true` | no |
| <a name="input_kms_key_id"></a> [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. When specifying `kms_key_id`, encrypted needs to be set to `true` | `string` | `null` | no |
| <a name="input_kms_key_arn"></a> [kms\_key\_arn](#input\_kms\_key\_arn) | The ARN for the KMS encryption key. When specifying `kms_key_arn`, encrypted needs to be set to `true` | `string` | `null` | no |
| <a name="input_lifecycle_policy"></a> [lifecycle\_policy](#input\_lifecycle\_policy) | A file system [lifecycle policy](https://docs.aws.amazon.com/efs/latest/ug/API_LifecyclePolicy.html) object | `any` | `{}` | no |
| <a name="input_mount_targets"></a> [mount\_targets](#input\_mount\_targets) | A map of mount target definitions to create | `any` | `{}` | no |
| <a name="input_name"></a> [name](#input\_name) | The name of the file system | `string` | `""` | no |
| <a name="input_override_policy_documents"></a> [override\_policy\_documents](#input\_override\_policy\_documents) | List of IAM policy documents that are merged together into the exported document. In merging, statements with non-blank `sid`s will override statements with the same `sid` | `list(string)` | `[]` | no |
| <a name="input_performance_mode"></a> [performance\_mode](#input\_performance\_mode) | The file system performance mode. Can be either `generalPurpose` or `maxIO`. Default is `generalPurpose` | `string` | `null` | no |
| <a name="input_policy_statements"></a> [policy\_statements](#input\_policy\_statements) | A map of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) for custom permission usage | `any` | `{}` | no |
| <a name="input_policy_statements"></a> [policy\_statements](#input\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) for custom permission usage | `any` | `[]` | no |
| <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. Only applicable with `throughput_mode` set to `provisioned` | `number` | `null` | no |
| <a name="input_replication_configuration_destination"></a> [replication\_configuration\_destination](#input\_replication\_configuration\_destination) | A destination configuration block | `any` | `{}` | no |
| <a name="input_security_group_description"></a> [security\_group\_description](#input\_security\_group\_description) | Security group description. Defaults to Managed by Terraform | `string` | `null` | no |
Expand Down
11 changes: 9 additions & 2 deletions examples/complete/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,26 @@ Note that this example may create resources which will incur monetary charges on

## Providers

No providers.
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.16 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_efs"></a> [efs](#module\_efs) | ../.. | n/a |
| <a name="module_efs_default"></a> [efs\_default](#module\_efs\_default) | ../.. | n/a |
| <a name="module_efs_disabled"></a> [efs\_disabled](#module\_efs\_disabled) | ../.. | n/a |
| <a name="module_kms"></a> [kms](#module\_kms) | terraform-aws-modules/kms/aws | ~> 1.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 |

## Resources

No resources.
| Name | Type |
|------|------|
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |

## Inputs

Expand Down
108 changes: 107 additions & 1 deletion examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,112 @@ locals {
region = "eu-west-1"
name = "efs-ex-${replace(basename(path.cwd), "_", "-")}"

azs = slice(data.aws_availability_zones.available.names, 0, 3)

tags = {
Name = local.name
Example = local.name
Repository = "https://github.com/terraform-aws-modules/terraform-aws-efs"
}
}

data "aws_availability_zones" "available" {}
data "aws_caller_identity" "current" {}

################################################################################
# EFS Module
################################################################################

module "efs" {
source = "../.."

# File system
name = local.name
creation_token = local.name
encrypted = true
kms_key_arn = module.kms.key_arn

performance_mode = "maxIO"
throughput_mode = "provisioned"
provisioned_throughput_in_mibps = 256

lifecycle_policy = {
transition_to_ia = "AFTER_30_DAYS"
}

# File system policy
attach_policy = true
bypass_policy_lockout_safety_check = false
policy_statements = [
{
sid = "Example"
actions = ["elasticfilesystem:ClientMount"]
principals = [
{
type = "AWS"
identifiers = [data.aws_caller_identity.current.arn]
}
]
}
]

# Mount targets / security group
mount_targets = { for k, v in toset(range(length(local.azs))) :
element(local.azs, k) => { subnet_id = element(module.vpc.private_subnets, k) }
}
security_group_description = "Example EFS security group"
security_group_vpc_id = module.vpc.vpc_id
security_group_rules = {
vpc = {
# relying on the defaults provdied for EFS/NFS (2049/TCP + ingress)
description = "NFS ingress from VPC private subnets"
cidr_blocks = module.vpc.private_subnets_cidr_blocks
}
}

# Access point(s)
access_points = {
posix_example = {
name = "posix-example"
posix_user = {
gid = 1001
uid = 1001
secondary_gids = [1002]
}

tags = {
Additionl = "yes"
}
}
root_example = {
root_directory = {
path = "/example"
creation_info = {
owner_gid = 1001
owner_uid = 1001
permissions = "755"
}
}
}
}

# Backup policy
enable_backup_policy = true

# Replication configuration
create_replication_configuration = true
replication_configuration_destination = {
region = "eu-west-2"
}

tags = local.tags
}

module "efs_default" {
source = "../.."

name = "${local.name}-default"

tags = local.tags
}

Expand All @@ -40,7 +132,7 @@ module "vpc" {
name = local.name
cidr = "10.99.0.0/18"

azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
azs = local.azs
public_subnets = ["10.99.0.0/24", "10.99.1.0/24", "10.99.2.0/24"]
private_subnets = ["10.99.3.0/24", "10.99.4.0/24", "10.99.5.0/24"]

Expand All @@ -50,3 +142,17 @@ module "vpc" {

tags = local.tags
}

module "kms" {
source = "terraform-aws-modules/kms/aws"
version = "~> 1.0"

aliases = ["efs/${local.name}"]
description = "EFS customer managed key"
enable_default_policy = true

# For example use only
deletion_window_in_days = 7

tags = local.tags
}
35 changes: 24 additions & 11 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,23 @@ resource "aws_efs_file_system" "this" {
creation_token = var.creation_token
performance_mode = var.performance_mode
encrypted = var.encrypted
kms_key_id = var.kms_key_id
kms_key_id = var.kms_key_arn
provisioned_throughput_in_mibps = var.provisioned_throughput_in_mibps
throughput_mode = var.throughput_mode

dynamic "lifecycle_policy" {
for_each = var.lifecycle_policy
for_each = length(var.lifecycle_policy) > 0 ? [var.lifecycle_policy] : []

content {
transition_to_ia = try(lifecycle_policy.value.transition_to_ia, null)
transition_to_primary_storage_class = try(lifecycle_policy.value.transition_to_primary_storage_class, null)
}
}

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

################################################################################
Expand All @@ -43,7 +46,7 @@ data "aws_iam_policy_document" "policy" {
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
resources = try(statement.value.resources, [aws_efs_file_system.this[0].arn], null)
not_resources = try(statement.value.not_resources, null)

dynamic "principals" {
Expand Down Expand Up @@ -77,9 +80,10 @@ data "aws_iam_policy_document" "policy" {
}

statement {
sid = "NonSecureTransport"
effect = "Deny"
actions = ["*"]
sid = "NonSecureTransport"
effect = "Deny"
actions = ["*"]
resources = [aws_efs_file_system.this[0].arn]

principals {
type = "AWS"
Expand Down Expand Up @@ -119,11 +123,15 @@ resource "aws_efs_mount_target" "this" {
# Security Group
################################################################################

locals {
security_group_name = try(coalesce(var.security_group_name, var.name), "")
}

resource "aws_security_group" "this" {
count = var.create && var.create_security_group ? 1 : 0
count = var.create && var.create_security_group && length(var.mount_targets) > 0 ? 1 : 0

name = var.security_group_use_name_prefix ? null : var.security_group_name
name_prefix = var.security_group_use_name_prefix ? "${var.security_group_name}-" : null
name = var.security_group_use_name_prefix ? null : local.security_group_name
name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null
description = var.security_group_description

revoke_rules_on_delete = true
Expand All @@ -137,6 +145,7 @@ resource "aws_security_group_rule" "this" {

security_group_id = aws_security_group.this[0].id

description = try(each.value.description, null)
type = try(each.value.type, "ingress")
from_port = try(each.value.from_port, 2049)
to_port = try(each.value.to_port, 2049)
Expand Down Expand Up @@ -185,7 +194,11 @@ resource "aws_efs_access_point" "this" {
}
}

tags = merge(var.tags, try(each.value.tags, {}))
tags = merge(
var.tags,
try(each.value.tags, {}),
{ Name = try(each.value.name, each.key) },
)
}

################################################################################
Expand Down
Loading

0 comments on commit b69550c

Please sign in to comment.