Skip to content

Commit b69550c

Browse files
committed
feat: Initial release of efs module 🎉
1 parent bc7ad90 commit b69550c

File tree

5 files changed

+240
-20
lines changed

5 files changed

+240
-20
lines changed

README.md

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,93 @@ See [`examples`](https://github.com/terraform-aws-modules/terraform-aws-efs/tree
1010
module "efs" {
1111
source = "terraform-aws-modules/efs/aws"
1212
13+
# File system
14+
name = "example"
15+
creation_token = "example-token"
16+
encrypted = true
17+
kms_key_arn = "arn:aws:kms:eu-west-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
18+
19+
performance_mode = "maxIO"
20+
throughput_mode = "provisioned"
21+
provisioned_throughput_in_mibps = 256
22+
23+
lifecycle_policy = {
24+
transition_to_ia = "AFTER_30_DAYS"
25+
}
26+
27+
# File system policy
28+
attach_policy = true
29+
bypass_policy_lockout_safety_check = false
30+
policy_statements = [
31+
{
32+
sid = "Example"
33+
actions = ["elasticfilesystem:ClientMount"]
34+
principals = [
35+
{
36+
type = "AWS"
37+
identifiers = ["arn:aws:iam::111122223333:role/EfsReadOnly"]
38+
}
39+
]
40+
}
41+
]
42+
43+
# Mount targets / security group
44+
mount_targets = {
45+
"eu-west-1a" = {
46+
subnet_id = "subnet-abcde012"
47+
}
48+
"eu-west-1b" = {
49+
subnet_id = "subnet-bcde012a"
50+
}
51+
"eu-west-1c" = {
52+
subnet_id = "subnet-fghi345a"
53+
}
54+
}
55+
security_group_description = "Example EFS security group"
56+
security_group_vpc_id = "vpc-1234556abcdef"
57+
security_group_rules = {
58+
vpc = {
59+
# relying on the defaults provdied for EFS/NFS (2049/TCP + ingress)
60+
description = "NFS ingress from VPC private subnets"
61+
cidr_blocks = ["10.99.3.0/24", "10.99.4.0/24", "10.99.5.0/24"]
62+
}
63+
}
64+
65+
# Access point(s)
66+
access_points = {
67+
posix_example = {
68+
name = "posix-example"
69+
posix_user = {
70+
gid = 1001
71+
uid = 1001
72+
secondary_gids = [1002]
73+
}
74+
75+
tags = {
76+
Additionl = "yes"
77+
}
78+
}
79+
root_example = {
80+
root_directory = {
81+
path = "/example"
82+
creation_info = {
83+
owner_gid = 1001
84+
owner_uid = 1001
85+
permissions = "755"
86+
}
87+
}
88+
}
89+
}
90+
91+
# Backup policy
92+
enable_backup_policy = true
93+
94+
# Replication configuration
95+
create_replication_configuration = true
96+
replication_configuration_destination = {
97+
region = "eu-west-2"
98+
}
99+
13100
tags = {
14101
Terraform = "true"
15102
Environment = "dev"
@@ -69,12 +156,13 @@ No modules.
69156
| <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 |
70157
| <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 |
71158
| <a name="input_encrypted"></a> [encrypted](#input\_encrypted) | If `true`, the disk will be encrypted | `bool` | `true` | no |
72-
| <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 |
159+
| <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 |
73160
| <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 |
74161
| <a name="input_mount_targets"></a> [mount\_targets](#input\_mount\_targets) | A map of mount target definitions to create | `any` | `{}` | no |
162+
| <a name="input_name"></a> [name](#input\_name) | The name of the file system | `string` | `""` | no |
75163
| <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 |
76164
| <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 |
77-
| <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 |
165+
| <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 |
78166
| <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 |
79167
| <a name="input_replication_configuration_destination"></a> [replication\_configuration\_destination](#input\_replication\_configuration\_destination) | A destination configuration block | `any` | `{}` | no |
80168
| <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 |

examples/complete/README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,26 @@ Note that this example may create resources which will incur monetary charges on
2626

2727
## Providers
2828

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

3133
## Modules
3234

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

3943
## Resources
4044

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

4350
## Inputs
4451

examples/complete/main.tf

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,112 @@ locals {
66
region = "eu-west-1"
77
name = "efs-ex-${replace(basename(path.cwd), "_", "-")}"
88

9+
azs = slice(data.aws_availability_zones.available.names, 0, 3)
10+
911
tags = {
1012
Name = local.name
1113
Example = local.name
1214
Repository = "https://github.com/terraform-aws-modules/terraform-aws-efs"
1315
}
1416
}
1517

18+
data "aws_availability_zones" "available" {}
19+
data "aws_caller_identity" "current" {}
20+
1621
################################################################################
1722
# EFS Module
1823
################################################################################
1924

2025
module "efs" {
2126
source = "../.."
2227

28+
# File system
29+
name = local.name
30+
creation_token = local.name
31+
encrypted = true
32+
kms_key_arn = module.kms.key_arn
33+
34+
performance_mode = "maxIO"
35+
throughput_mode = "provisioned"
36+
provisioned_throughput_in_mibps = 256
37+
38+
lifecycle_policy = {
39+
transition_to_ia = "AFTER_30_DAYS"
40+
}
41+
42+
# File system policy
43+
attach_policy = true
44+
bypass_policy_lockout_safety_check = false
45+
policy_statements = [
46+
{
47+
sid = "Example"
48+
actions = ["elasticfilesystem:ClientMount"]
49+
principals = [
50+
{
51+
type = "AWS"
52+
identifiers = [data.aws_caller_identity.current.arn]
53+
}
54+
]
55+
}
56+
]
57+
58+
# Mount targets / security group
59+
mount_targets = { for k, v in toset(range(length(local.azs))) :
60+
element(local.azs, k) => { subnet_id = element(module.vpc.private_subnets, k) }
61+
}
62+
security_group_description = "Example EFS security group"
63+
security_group_vpc_id = module.vpc.vpc_id
64+
security_group_rules = {
65+
vpc = {
66+
# relying on the defaults provdied for EFS/NFS (2049/TCP + ingress)
67+
description = "NFS ingress from VPC private subnets"
68+
cidr_blocks = module.vpc.private_subnets_cidr_blocks
69+
}
70+
}
71+
72+
# Access point(s)
73+
access_points = {
74+
posix_example = {
75+
name = "posix-example"
76+
posix_user = {
77+
gid = 1001
78+
uid = 1001
79+
secondary_gids = [1002]
80+
}
81+
82+
tags = {
83+
Additionl = "yes"
84+
}
85+
}
86+
root_example = {
87+
root_directory = {
88+
path = "/example"
89+
creation_info = {
90+
owner_gid = 1001
91+
owner_uid = 1001
92+
permissions = "755"
93+
}
94+
}
95+
}
96+
}
97+
98+
# Backup policy
99+
enable_backup_policy = true
100+
101+
# Replication configuration
102+
create_replication_configuration = true
103+
replication_configuration_destination = {
104+
region = "eu-west-2"
105+
}
106+
107+
tags = local.tags
108+
}
109+
110+
module "efs_default" {
111+
source = "../.."
112+
113+
name = "${local.name}-default"
114+
23115
tags = local.tags
24116
}
25117

@@ -40,7 +132,7 @@ module "vpc" {
40132
name = local.name
41133
cidr = "10.99.0.0/18"
42134

43-
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
135+
azs = local.azs
44136
public_subnets = ["10.99.0.0/24", "10.99.1.0/24", "10.99.2.0/24"]
45137
private_subnets = ["10.99.3.0/24", "10.99.4.0/24", "10.99.5.0/24"]
46138

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

51143
tags = local.tags
52144
}
145+
146+
module "kms" {
147+
source = "terraform-aws-modules/kms/aws"
148+
version = "~> 1.0"
149+
150+
aliases = ["efs/${local.name}"]
151+
description = "EFS customer managed key"
152+
enable_default_policy = true
153+
154+
# For example use only
155+
deletion_window_in_days = 7
156+
157+
tags = local.tags
158+
}

main.tf

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,23 @@ resource "aws_efs_file_system" "this" {
99
creation_token = var.creation_token
1010
performance_mode = var.performance_mode
1111
encrypted = var.encrypted
12-
kms_key_id = var.kms_key_id
12+
kms_key_id = var.kms_key_arn
1313
provisioned_throughput_in_mibps = var.provisioned_throughput_in_mibps
1414
throughput_mode = var.throughput_mode
1515

1616
dynamic "lifecycle_policy" {
17-
for_each = var.lifecycle_policy
17+
for_each = length(var.lifecycle_policy) > 0 ? [var.lifecycle_policy] : []
1818

1919
content {
2020
transition_to_ia = try(lifecycle_policy.value.transition_to_ia, null)
2121
transition_to_primary_storage_class = try(lifecycle_policy.value.transition_to_primary_storage_class, null)
2222
}
2323
}
2424

25-
tags = var.tags
25+
tags = merge(
26+
var.tags,
27+
{ Name = var.name },
28+
)
2629
}
2730

2831
################################################################################
@@ -43,7 +46,7 @@ data "aws_iam_policy_document" "policy" {
4346
actions = try(statement.value.actions, null)
4447
not_actions = try(statement.value.not_actions, null)
4548
effect = try(statement.value.effect, null)
46-
resources = try(statement.value.resources, null)
49+
resources = try(statement.value.resources, [aws_efs_file_system.this[0].arn], null)
4750
not_resources = try(statement.value.not_resources, null)
4851

4952
dynamic "principals" {
@@ -77,9 +80,10 @@ data "aws_iam_policy_document" "policy" {
7780
}
7881

7982
statement {
80-
sid = "NonSecureTransport"
81-
effect = "Deny"
82-
actions = ["*"]
83+
sid = "NonSecureTransport"
84+
effect = "Deny"
85+
actions = ["*"]
86+
resources = [aws_efs_file_system.this[0].arn]
8387

8488
principals {
8589
type = "AWS"
@@ -119,11 +123,15 @@ resource "aws_efs_mount_target" "this" {
119123
# Security Group
120124
################################################################################
121125

126+
locals {
127+
security_group_name = try(coalesce(var.security_group_name, var.name), "")
128+
}
129+
122130
resource "aws_security_group" "this" {
123-
count = var.create && var.create_security_group ? 1 : 0
131+
count = var.create && var.create_security_group && length(var.mount_targets) > 0 ? 1 : 0
124132

125-
name = var.security_group_use_name_prefix ? null : var.security_group_name
126-
name_prefix = var.security_group_use_name_prefix ? "${var.security_group_name}-" : null
133+
name = var.security_group_use_name_prefix ? null : local.security_group_name
134+
name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null
127135
description = var.security_group_description
128136

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

138146
security_group_id = aws_security_group.this[0].id
139147

148+
description = try(each.value.description, null)
140149
type = try(each.value.type, "ingress")
141150
from_port = try(each.value.from_port, 2049)
142151
to_port = try(each.value.to_port, 2049)
@@ -185,7 +194,11 @@ resource "aws_efs_access_point" "this" {
185194
}
186195
}
187196

188-
tags = merge(var.tags, try(each.value.tags, {}))
197+
tags = merge(
198+
var.tags,
199+
try(each.value.tags, {}),
200+
{ Name = try(each.value.name, each.key) },
201+
)
189202
}
190203

191204
################################################################################

0 commit comments

Comments
 (0)