├── examples ├── complete │ ├── variables.tf │ ├── versions.tf │ ├── outputs.tf │ ├── README.md │ └── main.tf └── README.md ├── wrappers ├── outputs.tf ├── versions.tf ├── variables.tf ├── README.md └── main.tf ├── versions.tf ├── .editorconfig ├── .gitignore ├── .github └── workflows │ ├── lock.yml │ ├── release.yml │ ├── stale-actions.yaml │ ├── pr-title.yml │ └── pre-commit.yml ├── .releaserc.json ├── .pre-commit-config.yaml ├── outputs.tf ├── docs └── UPGRADE-2.0.md ├── CHANGELOG.md ├── LICENSE ├── variables.tf ├── main.tf └── README.md /examples/complete/variables.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /wrappers/outputs.tf: -------------------------------------------------------------------------------- 1 | output "wrapper" { 2 | description = "Map of outputs of a wrapper." 3 | value = module.wrapper 4 | # sensitive = false # No sensitive module output found 5 | } 6 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.12" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /wrappers/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.12" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/complete/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.12" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /wrappers/variables.tf: -------------------------------------------------------------------------------- 1 | variable "defaults" { 2 | description = "Map of default values which will be used for each item." 3 | type = any 4 | default = {} 5 | } 6 | 7 | variable "items" { 8 | description = "Maps of items to create a wrapper from. Values are passed through to the module." 9 | type = any 10 | default = {} 11 | } 12 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Please note - the examples provided serve two primary means: 4 | 5 | 1. Show users working examples of the various ways in which the module can be configured and features supported 6 | 2. A means of testing/validating module changes 7 | 8 | Please do not mistake the examples provided as "best practices". It is up to users to consult the AWS service documentation for best practices, usage recommendations, etc. 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | # Uses editorconfig to maintain consistent coding styles 3 | 4 | # top-most EditorConfig file 5 | root = true 6 | 7 | # Unix-style newlines with a newline ending every file 8 | [*] 9 | charset = utf-8 10 | end_of_line = lf 11 | indent_size = 2 12 | indent_style = space 13 | insert_final_newline = true 14 | max_line_length = 80 15 | trim_trailing_whitespace = true 16 | 17 | [*.{tf,tfvars}] 18 | indent_size = 2 19 | indent_style = space 20 | 21 | [*.md] 22 | max_line_length = 0 23 | trim_trailing_whitespace = false 24 | 25 | [Makefile] 26 | tab_width = 2 27 | indent_style = tab 28 | 29 | [COMMIT_EDITMSG] 30 | max_line_length = 0 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # Terraform lockfile 5 | .terraform.lock.hcl 6 | 7 | # .tfstate files 8 | *.tfstate 9 | *.tfstate.* 10 | 11 | # Crash log files 12 | crash.log 13 | 14 | # Exclude all .tfvars files, which are likely to contain sentitive data, such as 15 | # password, private keys, and other secrets. These should not be part of version 16 | # control as they are data points which are potentially sensitive and subject 17 | # to change depending on the environment. 18 | *.tfvars 19 | 20 | # Ignore override files as they are usually used to override resources locally and so 21 | # are not checked in 22 | override.tf 23 | override.tf.json 24 | *_override.tf 25 | *_override.tf.json 26 | 27 | # Ignore CLI configuration files 28 | .terraformrc 29 | terraform.rc 30 | 31 | # Lambda build artifacts 32 | builds/ 33 | __pycache__/ 34 | *.zip 35 | .tox 36 | 37 | # Local editors/macos files 38 | .DS_Store 39 | .idea 40 | -------------------------------------------------------------------------------- /.github/workflows/lock.yml: -------------------------------------------------------------------------------- 1 | name: 'Lock Threads' 2 | 3 | on: 4 | schedule: 5 | - cron: '50 1 * * *' 6 | 7 | jobs: 8 | lock: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: dessant/lock-threads@v5 12 | with: 13 | github-token: ${{ secrets.GITHUB_TOKEN }} 14 | issue-comment: > 15 | I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues. 16 | If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. 17 | issue-inactive-days: '30' 18 | pr-comment: > 19 | I'm going to lock this pull request because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues. 20 | If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. 21 | pr-inactive-days: '30' 22 | -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | "main", 4 | "master" 5 | ], 6 | "ci": false, 7 | "plugins": [ 8 | [ 9 | "@semantic-release/commit-analyzer", 10 | { 11 | "preset": "conventionalcommits" 12 | } 13 | ], 14 | [ 15 | "@semantic-release/release-notes-generator", 16 | { 17 | "preset": "conventionalcommits" 18 | } 19 | ], 20 | [ 21 | "@semantic-release/github", 22 | { 23 | "successComment": "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:", 24 | "labels": false, 25 | "releasedLabels": false 26 | } 27 | ], 28 | [ 29 | "@semantic-release/changelog", 30 | { 31 | "changelogFile": "CHANGELOG.md", 32 | "changelogTitle": "# Changelog\n\nAll notable changes to this project will be documented in this file." 33 | } 34 | ], 35 | [ 36 | "@semantic-release/git", 37 | { 38 | "assets": [ 39 | "CHANGELOG.md" 40 | ], 41 | "message": "chore(release): version ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" 42 | } 43 | ] 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | - master 9 | paths: 10 | - '**/*.tpl' 11 | - '**/*.py' 12 | - '**/*.tf' 13 | - '.github/workflows/release.yml' 14 | 15 | jobs: 16 | release: 17 | name: Release 18 | runs-on: ubuntu-latest 19 | # Skip running release workflow on forks 20 | if: github.repository_owner == 'terraform-aws-modules' 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v5 24 | with: 25 | persist-credentials: false 26 | fetch-depth: 0 27 | 28 | - name: Set correct Node.js version 29 | uses: actions/setup-node@v6 30 | with: 31 | node-version: 24 32 | 33 | - name: Install dependencies 34 | run: | 35 | npm install \ 36 | @semantic-release/changelog@6.0.3 \ 37 | @semantic-release/git@10.0.1 \ 38 | conventional-changelog-conventionalcommits@9.1.0 39 | 40 | - name: Release 41 | uses: cycjimmy/semantic-release-action@v5 42 | with: 43 | semantic_version: 25.0.0 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }} 46 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/antonbabenko/pre-commit-terraform 3 | rev: v1.103.0 4 | hooks: 5 | - id: terraform_fmt 6 | - id: terraform_wrapper_module_for_each 7 | - id: terraform_docs 8 | args: 9 | - '--args=--lockfile=false' 10 | - id: terraform_tflint 11 | args: 12 | - '--args=--only=terraform_deprecated_interpolation' 13 | - '--args=--only=terraform_deprecated_index' 14 | - '--args=--only=terraform_unused_declarations' 15 | - '--args=--only=terraform_comment_syntax' 16 | - '--args=--only=terraform_documented_outputs' 17 | - '--args=--only=terraform_documented_variables' 18 | - '--args=--only=terraform_typed_variables' 19 | - '--args=--only=terraform_module_pinned_source' 20 | - '--args=--only=terraform_naming_convention' 21 | - '--args=--only=terraform_required_version' 22 | - '--args=--only=terraform_required_providers' 23 | - '--args=--only=terraform_standard_module_structure' 24 | - '--args=--only=terraform_workspace_remote' 25 | - id: terraform_validate 26 | - repo: https://github.com/pre-commit/pre-commit-hooks 27 | rev: v6.0.0 28 | hooks: 29 | - id: check-merge-conflict 30 | - id: end-of-file-fixer 31 | - id: trailing-whitespace 32 | -------------------------------------------------------------------------------- /.github/workflows/stale-actions.yaml: -------------------------------------------------------------------------------- 1 | name: 'Mark or close stale issues and PRs' 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v10 11 | with: 12 | repo-token: ${{ secrets.GITHUB_TOKEN }} 13 | # Staling issues and PR's 14 | days-before-stale: 30 15 | stale-issue-label: stale 16 | stale-pr-label: stale 17 | stale-issue-message: | 18 | This issue has been automatically marked as stale because it has been open 30 days 19 | with no activity. Remove stale label or comment or this issue will be closed in 10 days 20 | stale-pr-message: | 21 | This PR has been automatically marked as stale because it has been open 30 days 22 | with no activity. Remove stale label or comment or this PR will be closed in 10 days 23 | # Not stale if have this labels or part of milestone 24 | exempt-issue-labels: bug,wip,on-hold 25 | exempt-pr-labels: bug,wip,on-hold 26 | exempt-all-milestones: true 27 | # Close issue operations 28 | # Label will be automatically removed if the issues are no longer closed nor locked. 29 | days-before-close: 10 30 | delete-branch: true 31 | close-issue-message: This issue was automatically closed because of stale in 10 days 32 | close-pr-message: This PR was automatically closed because of stale in 10 days 33 | -------------------------------------------------------------------------------- /.github/workflows/pr-title.yml: -------------------------------------------------------------------------------- 1 | name: 'Validate PR title' 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | jobs: 11 | main: 12 | name: Validate PR title 13 | runs-on: ubuntu-latest 14 | steps: 15 | # Please look up the latest version from 16 | # https://github.com/amannn/action-semantic-pull-request/releases 17 | - uses: amannn/action-semantic-pull-request@v6.1.1 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | with: 21 | # Configure which types are allowed. 22 | # Default: https://github.com/commitizen/conventional-commit-types 23 | types: | 24 | fix 25 | feat 26 | docs 27 | ci 28 | chore 29 | # Configure that a scope must always be provided. 30 | requireScope: false 31 | # Configure additional validation for the subject based on a regex. 32 | # This example ensures the subject starts with an uppercase character. 33 | subjectPattern: ^[A-Z].+$ 34 | # If `subjectPattern` is configured, you can use this property to override 35 | # the default error message that is shown when the pattern doesn't match. 36 | # The variables `subject` and `title` can be used within the message. 37 | subjectPatternError: | 38 | The subject "{subject}" found in the pull request title "{title}" 39 | didn't match the configured pattern. Please ensure that the subject 40 | starts with an uppercase character. 41 | # For work-in-progress PRs you can typically use draft pull requests 42 | # from Github. However, private repositories on the free plan don't have 43 | # this option and therefore this action allows you to opt-in to using the 44 | # special "[WIP]" prefix to indicate this state. This will avoid the 45 | # validation of the PR title and the pull request checks remain pending. 46 | # Note that a second check will be reported if this is enabled. 47 | wip: true 48 | # When using "Squash and merge" on a PR with only one commit, GitHub 49 | # will suggest using that commit message instead of the PR title for the 50 | # merge commit, and it's easy to commit this by mistake. Enable this option 51 | # to also validate the commit message for one commit PRs. 52 | validateSingleCommit: false 53 | -------------------------------------------------------------------------------- /examples/complete/outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # File System 3 | ################################################################################ 4 | 5 | output "arn" { 6 | description = "Amazon Resource Name of the file system" 7 | value = module.efs.arn 8 | } 9 | 10 | output "id" { 11 | description = "The ID that identifies the file system (e.g., `fs-ccfc0d65`)" 12 | value = module.efs.id 13 | } 14 | 15 | output "dns_name" { 16 | description = "The DNS name for the filesystem per [documented convention](http://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html)" 17 | value = module.efs.dns_name 18 | } 19 | 20 | output "size_in_bytes" { 21 | description = "The latest known metered size (in bytes) of data stored in the file system, the value is not the exact size that the file system was at any point in time" 22 | value = module.efs.size_in_bytes 23 | } 24 | 25 | ################################################################################ 26 | # Mount Target(s) 27 | ################################################################################ 28 | 29 | output "mount_targets" { 30 | description = "Map of mount targets created and their attributes" 31 | value = module.efs.mount_targets 32 | } 33 | 34 | ################################################################################ 35 | # Security Group 36 | ################################################################################ 37 | 38 | output "security_group_arn" { 39 | description = "ARN of the security group" 40 | value = module.efs.security_group_arn 41 | } 42 | 43 | output "security_group_id" { 44 | description = "ID of the security group" 45 | value = module.efs.security_group_id 46 | } 47 | 48 | ################################################################################ 49 | # Access Point(s) 50 | ################################################################################ 51 | 52 | output "access_points" { 53 | description = "Map of access points created and their attributes" 54 | value = module.efs.access_points 55 | } 56 | 57 | ################################################################################ 58 | # Replication Configuration 59 | ################################################################################ 60 | 61 | output "replication_configuration_destination_file_system_id" { 62 | description = "The file system ID of the replica" 63 | value = module.efs.replication_configuration_destination_file_system_id 64 | } 65 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # File System 3 | ################################################################################ 4 | 5 | output "arn" { 6 | description = "Amazon Resource Name of the file system" 7 | value = try(aws_efs_file_system.this[0].arn, null) 8 | } 9 | 10 | output "id" { 11 | description = "The ID that identifies the file system (e.g., `fs-ccfc0d65`)" 12 | value = try(aws_efs_file_system.this[0].id, null) 13 | } 14 | 15 | output "dns_name" { 16 | description = "The DNS name for the filesystem per [documented convention](http://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html)" 17 | value = try(aws_efs_file_system.this[0].dns_name, null) 18 | } 19 | 20 | output "size_in_bytes" { 21 | description = "The latest known metered size (in bytes) of data stored in the file system, the value is not the exact size that the file system was at any point in time" 22 | value = try(aws_efs_file_system.this[0].size_in_bytes, null) 23 | } 24 | 25 | ################################################################################ 26 | # Mount Target(s) 27 | ################################################################################ 28 | 29 | output "mount_targets" { 30 | description = "Map of mount targets created and their attributes" 31 | value = aws_efs_mount_target.this 32 | } 33 | 34 | ################################################################################ 35 | # Security Group 36 | ################################################################################ 37 | 38 | output "security_group_arn" { 39 | description = "ARN of the security group" 40 | value = try(aws_security_group.this[0].arn, null) 41 | } 42 | 43 | output "security_group_id" { 44 | description = "ID of the security group" 45 | value = try(aws_security_group.this[0].id, null) 46 | } 47 | 48 | ################################################################################ 49 | # Access Point(s) 50 | ################################################################################ 51 | 52 | output "access_points" { 53 | description = "Map of access points created and their attributes" 54 | value = aws_efs_access_point.this 55 | } 56 | 57 | ################################################################################ 58 | # Replication Configuration 59 | ################################################################################ 60 | 61 | output "replication_configuration_destination_file_system_id" { 62 | description = "The file system ID of the replica" 63 | value = try(aws_efs_replication_configuration.this[0].destination[0].file_system_id, null) 64 | } 65 | -------------------------------------------------------------------------------- /wrappers/README.md: -------------------------------------------------------------------------------- 1 | # Wrapper for the root module 2 | 3 | The configuration in this directory contains an implementation of a single module wrapper pattern, which allows managing several copies of a module in places where using the native Terraform 0.13+ `for_each` feature is not feasible (e.g., with Terragrunt). 4 | 5 | You may want to use a single Terragrunt configuration file to manage multiple resources without duplicating `terragrunt.hcl` files for each copy of the same module. 6 | 7 | This wrapper does not implement any extra functionality. 8 | 9 | ## Usage with Terragrunt 10 | 11 | `terragrunt.hcl`: 12 | 13 | ```hcl 14 | terraform { 15 | source = "tfr:///terraform-aws-modules/efs/aws//wrappers" 16 | # Alternative source: 17 | # source = "git::git@github.com:terraform-aws-modules/terraform-aws-efs.git//wrappers?ref=master" 18 | } 19 | 20 | inputs = { 21 | defaults = { # Default values 22 | create = true 23 | tags = { 24 | Terraform = "true" 25 | Environment = "dev" 26 | } 27 | } 28 | 29 | items = { 30 | my-item = { 31 | # omitted... can be any argument supported by the module 32 | } 33 | my-second-item = { 34 | # omitted... can be any argument supported by the module 35 | } 36 | # omitted... 37 | } 38 | } 39 | ``` 40 | 41 | ## Usage with Terraform 42 | 43 | ```hcl 44 | module "wrapper" { 45 | source = "terraform-aws-modules/efs/aws//wrappers" 46 | 47 | defaults = { # Default values 48 | create = true 49 | tags = { 50 | Terraform = "true" 51 | Environment = "dev" 52 | } 53 | } 54 | 55 | items = { 56 | my-item = { 57 | # omitted... can be any argument supported by the module 58 | } 59 | my-second-item = { 60 | # omitted... can be any argument supported by the module 61 | } 62 | # omitted... 63 | } 64 | } 65 | ``` 66 | 67 | ## Example: Manage multiple S3 buckets in one Terragrunt layer 68 | 69 | `eu-west-1/s3-buckets/terragrunt.hcl`: 70 | 71 | ```hcl 72 | terraform { 73 | source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers" 74 | # Alternative source: 75 | # source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master" 76 | } 77 | 78 | inputs = { 79 | defaults = { 80 | force_destroy = true 81 | 82 | attach_elb_log_delivery_policy = true 83 | attach_lb_log_delivery_policy = true 84 | attach_deny_insecure_transport_policy = true 85 | attach_require_latest_tls_policy = true 86 | } 87 | 88 | items = { 89 | bucket1 = { 90 | bucket = "my-random-bucket-1" 91 | } 92 | bucket2 = { 93 | bucket = "my-random-bucket-2" 94 | tags = { 95 | Secure = "probably" 96 | } 97 | } 98 | } 99 | } 100 | ``` 101 | -------------------------------------------------------------------------------- /examples/complete/README.md: -------------------------------------------------------------------------------- 1 | # Complete AWS EFS Example 2 | 3 | Configuration in this directory creates: 4 | 5 | - A "complete" EFS file system which demonstrates the various configurations that are supported by the module 6 | - A "default" EFS file system which demonstrates the default configurations provided by the module 7 | - A disabled EFS file system 8 | 9 | ## Usage 10 | 11 | To run this example you need to execute: 12 | 13 | ```bash 14 | $ terraform init 15 | $ terraform plan 16 | $ terraform apply 17 | ``` 18 | 19 | Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources. 20 | 21 | 22 | ## Requirements 23 | 24 | | Name | Version | 25 | |------|---------| 26 | | [terraform](#requirement\_terraform) | >= 1.5.7 | 27 | | [aws](#requirement\_aws) | >= 6.12 | 28 | 29 | ## Providers 30 | 31 | | Name | Version | 32 | |------|---------| 33 | | [aws](#provider\_aws) | >= 6.12 | 34 | 35 | ## Modules 36 | 37 | | Name | Source | Version | 38 | |------|--------|---------| 39 | | [efs](#module\_efs) | ../.. | n/a | 40 | | [efs\_default](#module\_efs\_default) | ../.. | n/a | 41 | | [efs\_disabled](#module\_efs\_disabled) | ../.. | n/a | 42 | | [kms](#module\_kms) | terraform-aws-modules/kms/aws | ~> 1.0 | 43 | | [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 | 44 | 45 | ## Resources 46 | 47 | | Name | Type | 48 | |------|------| 49 | | [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | 50 | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | 51 | 52 | ## Inputs 53 | 54 | No inputs. 55 | 56 | ## Outputs 57 | 58 | | Name | Description | 59 | |------|-------------| 60 | | [access\_points](#output\_access\_points) | Map of access points created and their attributes | 61 | | [arn](#output\_arn) | Amazon Resource Name of the file system | 62 | | [dns\_name](#output\_dns\_name) | The DNS name for the filesystem per [documented convention](http://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html) | 63 | | [id](#output\_id) | The ID that identifies the file system (e.g., `fs-ccfc0d65`) | 64 | | [mount\_targets](#output\_mount\_targets) | Map of mount targets created and their attributes | 65 | | [replication\_configuration\_destination\_file\_system\_id](#output\_replication\_configuration\_destination\_file\_system\_id) | The file system ID of the replica | 66 | | [security\_group\_arn](#output\_security\_group\_arn) | ARN of the security group | 67 | | [security\_group\_id](#output\_security\_group\_id) | ID of the security group | 68 | | [size\_in\_bytes](#output\_size\_in\_bytes) | The latest known metered size (in bytes) of data stored in the file system, the value is not the exact size that the file system was at any point in time | 69 | 70 | 71 | Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-efs/blob/master/LICENSE). 72 | -------------------------------------------------------------------------------- /wrappers/main.tf: -------------------------------------------------------------------------------- 1 | module "wrapper" { 2 | source = "../" 3 | 4 | for_each = var.items 5 | 6 | access_points = try(each.value.access_points, var.defaults.access_points, {}) 7 | attach_policy = try(each.value.attach_policy, var.defaults.attach_policy, true) 8 | availability_zone_name = try(each.value.availability_zone_name, var.defaults.availability_zone_name, null) 9 | bypass_policy_lockout_safety_check = try(each.value.bypass_policy_lockout_safety_check, var.defaults.bypass_policy_lockout_safety_check, null) 10 | create = try(each.value.create, var.defaults.create, true) 11 | create_backup_policy = try(each.value.create_backup_policy, var.defaults.create_backup_policy, true) 12 | create_replication_configuration = try(each.value.create_replication_configuration, var.defaults.create_replication_configuration, false) 13 | create_security_group = try(each.value.create_security_group, var.defaults.create_security_group, true) 14 | creation_token = try(each.value.creation_token, var.defaults.creation_token, null) 15 | deny_nonsecure_transport = try(each.value.deny_nonsecure_transport, var.defaults.deny_nonsecure_transport, true) 16 | deny_nonsecure_transport_via_mount_target = try(each.value.deny_nonsecure_transport_via_mount_target, var.defaults.deny_nonsecure_transport_via_mount_target, true) 17 | enable_backup_policy = try(each.value.enable_backup_policy, var.defaults.enable_backup_policy, true) 18 | encrypted = try(each.value.encrypted, var.defaults.encrypted, true) 19 | kms_key_arn = try(each.value.kms_key_arn, var.defaults.kms_key_arn, null) 20 | lifecycle_policy = try(each.value.lifecycle_policy, var.defaults.lifecycle_policy, {}) 21 | mount_targets = try(each.value.mount_targets, var.defaults.mount_targets, {}) 22 | name = try(each.value.name, var.defaults.name, "") 23 | override_policy_documents = try(each.value.override_policy_documents, var.defaults.override_policy_documents, []) 24 | performance_mode = try(each.value.performance_mode, var.defaults.performance_mode, null) 25 | policy_statements = try(each.value.policy_statements, var.defaults.policy_statements, null) 26 | protection = try(each.value.protection, var.defaults.protection, null) 27 | provisioned_throughput_in_mibps = try(each.value.provisioned_throughput_in_mibps, var.defaults.provisioned_throughput_in_mibps, null) 28 | region = try(each.value.region, var.defaults.region, null) 29 | replication_configuration_destination = try(each.value.replication_configuration_destination, var.defaults.replication_configuration_destination, null) 30 | security_group_description = try(each.value.security_group_description, var.defaults.security_group_description, null) 31 | security_group_egress_rules = try(each.value.security_group_egress_rules, var.defaults.security_group_egress_rules, {}) 32 | security_group_ingress_rules = try(each.value.security_group_ingress_rules, var.defaults.security_group_ingress_rules, {}) 33 | security_group_name = try(each.value.security_group_name, var.defaults.security_group_name, null) 34 | security_group_use_name_prefix = try(each.value.security_group_use_name_prefix, var.defaults.security_group_use_name_prefix, false) 35 | security_group_vpc_id = try(each.value.security_group_vpc_id, var.defaults.security_group_vpc_id, null) 36 | source_policy_documents = try(each.value.source_policy_documents, var.defaults.source_policy_documents, []) 37 | tags = try(each.value.tags, var.defaults.tags, {}) 38 | throughput_mode = try(each.value.throughput_mode, var.defaults.throughput_mode, null) 39 | } 40 | -------------------------------------------------------------------------------- /docs/UPGRADE-2.0.md: -------------------------------------------------------------------------------- 1 | # Upgrade from v1.x to v2.x 2 | 3 | Please consult the `examples` directory for reference example configurations. If you find a bug, please open an issue with supporting configuration to reproduce. 4 | 5 | ## List of backwards incompatible changes 6 | 7 | - Terraform `v1.5.7` is now minimum supported version 8 | - AWS provider `v6.12` is now minimum supported version 9 | - `security_group_rules` has been split into `security_group_ingress_rules` and `security_group_egress_rules` to better match the AWS API and allow for more flexibility in defining security group rules. 10 | - `policy_statements` changed from type `any` to `map` 11 | 12 | ## Additional changes 13 | 14 | ### Added 15 | 16 | - Support for `region` parameter to specify the AWS region for the resources created if different from the provider region. 17 | 18 | ### Modified 19 | 20 | - Variable definitions now contain detailed `object` types in place of the previously used any type. 21 | 22 | ### Variable and output changes 23 | 24 | 1. Removed variables: 25 | 26 | - `security_group_rules` 27 | 28 | 2. Renamed variables: 29 | 30 | - None 31 | 32 | 3. Added variables: 33 | 34 | - `security_group_ingress_rules` 35 | - `security_group_egress_rules` 36 | 37 | 4. Removed outputs: 38 | 39 | - None 40 | 41 | 5. Renamed outputs: 42 | 43 | - None 44 | 45 | 6. Added outputs: 46 | 47 | - None 48 | 49 | ## Upgrade Migrations 50 | 51 | ### Before 2.x Example 52 | 53 | ```hcl 54 | module "efs" { 55 | source = "terraform-aws-modules/efs/aws" 56 | version = "~> 1.0" 57 | 58 | # Truncated for brevity ... 59 | 60 | # Security Groups 61 | security_group_rules = { 62 | vpc = { 63 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 64 | description = "NFS ingress from VPC private subnets" 65 | cidr_blocks = module.vpc.private_subnets_cidr_blocks 66 | } 67 | } 68 | 69 | # EFS Policy Statements 70 | policy_statements = [ 71 | { 72 | sid = "Example" 73 | actions = ["elasticfilesystem:ClientMount"] 74 | principals = [ 75 | { 76 | type = "AWS" 77 | identifiers = [data.aws_caller_identity.current.arn] 78 | } 79 | ] 80 | } 81 | ] 82 | } 83 | ``` 84 | 85 | ### After 2.x Example 86 | 87 | ```hcl 88 | module "efs" { 89 | source = "terraform-aws-modules/efs/aws" 90 | version = "~> 2.0" 91 | 92 | # Truncated for brevity ... 93 | 94 | # Security Groups 95 | security_group_ingress_rules = { 96 | vpc_1 = { 97 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 98 | description = "NFS ingress from VPC private subnets" 99 | cidr_ipv4 = element(module.vpc.private_subnets_cidr_blocks, 0) 100 | } 101 | vpc_2 = { 102 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 103 | description = "NFS ingress from VPC private subnets" 104 | cidr_ipv4 = element(module.vpc.private_subnets_cidr_blocks, 1) 105 | } 106 | vpc_3 = { 107 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 108 | description = "NFS ingress from VPC private subnets" 109 | cidr_ipv4 = element(module.vpc.private_subnets_cidr_blocks, 2) 110 | } 111 | } 112 | 113 | # EFS policy statements 114 | policy_statements = { 115 | example = { 116 | sid = "Example" 117 | actions = ["elasticfilesystem:ClientMount"] 118 | principals = [ 119 | { 120 | type = "AWS" 121 | identifiers = [data.aws_caller_identity.current.arn] 122 | } 123 | ] 124 | } 125 | } 126 | } 127 | ``` 128 | 129 | ### State Changes 130 | 131 | Due to the change from `aws_security_group_rule` to `aws_vpc_security_group_ingress_rule` and `aws_vpc_security_group_egress_rule`, the following reference state changes are required to maintain the current security group rules. (Note: these are different resources so they cannot be moved with `terraform mv ...`) 132 | 133 | ```sh 134 | terraform state rm 'module.efs.aws_security_group_rule.this["vpc"]' 135 | terraform state import 'module.efs.aws_vpc_security_group_ingress_rule.this["vpc_1"]' 'sgr-xxx' 136 | terraform state import 'module.efs.aws_vpc_security_group_ingress_rule.this["vpc_2"]' 'sgr-xxx' 137 | terraform state import 'module.efs.aws_vpc_security_group_ingress_rule.this["vpc_3"]' 'sgr-xxx' 138 | ``` 139 | -------------------------------------------------------------------------------- /examples/complete/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = local.region 3 | } 4 | 5 | locals { 6 | region = "eu-west-1" 7 | name = "ex-${basename(path.cwd)}" 8 | 9 | azs = slice(data.aws_availability_zones.available.names, 0, 3) 10 | 11 | tags = { 12 | Name = local.name 13 | Example = local.name 14 | Repository = "https://github.com/terraform-aws-modules/terraform-aws-efs" 15 | } 16 | } 17 | 18 | data "aws_availability_zones" "available" {} 19 | data "aws_caller_identity" "current" {} 20 | 21 | ################################################################################ 22 | # EFS Module 23 | ################################################################################ 24 | 25 | module "efs" { 26 | source = "../.." 27 | 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 | # NB! PROVISIONED TROUGHPUT MODE WITH 256 MIBPS IS EXPENSIVE ~$1500/month 36 | # throughput_mode = "provisioned" 37 | # provisioned_throughput_in_mibps = 256 38 | 39 | lifecycle_policy = { 40 | transition_to_ia = "AFTER_30_DAYS" 41 | transition_to_primary_storage_class = "AFTER_1_ACCESS" 42 | } 43 | 44 | # File system policy 45 | attach_policy = true 46 | deny_nonsecure_transport_via_mount_target = false 47 | bypass_policy_lockout_safety_check = false 48 | policy_statements = { 49 | example = { 50 | sid = "Example" 51 | actions = ["elasticfilesystem:ClientMount"] 52 | principals = [ 53 | { 54 | type = "AWS" 55 | identifiers = [data.aws_caller_identity.current.arn] 56 | } 57 | ] 58 | } 59 | } 60 | 61 | # Mount targets / security group 62 | mount_targets = { for k, v in zipmap(local.azs, module.vpc.private_subnets) : k => { subnet_id = v } } 63 | security_group_description = "Example EFS security group" 64 | security_group_vpc_id = module.vpc.vpc_id 65 | security_group_ingress_rules = { 66 | vpc_1 = { 67 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 68 | description = "NFS ingress from VPC private subnets" 69 | cidr_ipv4 = element(module.vpc.private_subnets_cidr_blocks, 0) 70 | } 71 | vpc_2 = { 72 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 73 | description = "NFS ingress from VPC private subnets" 74 | cidr_ipv4 = element(module.vpc.private_subnets_cidr_blocks, 1) 75 | } 76 | vpc_3 = { 77 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 78 | description = "NFS ingress from VPC private subnets" 79 | cidr_ipv4 = element(module.vpc.private_subnets_cidr_blocks, 2) 80 | } 81 | } 82 | 83 | # Access point(s) 84 | access_points = { 85 | posix_example = { 86 | name = "posix-example" 87 | posix_user = { 88 | gid = 1001 89 | uid = 1001 90 | secondary_gids = [1002] 91 | } 92 | 93 | tags = { 94 | Additionl = "yes" 95 | } 96 | } 97 | root_example = { 98 | root_directory = { 99 | path = "/example" 100 | creation_info = { 101 | owner_gid = 1001 102 | owner_uid = 1001 103 | permissions = "755" 104 | } 105 | } 106 | } 107 | } 108 | 109 | # Backup policy 110 | enable_backup_policy = true 111 | 112 | # Replication configuration 113 | create_replication_configuration = true 114 | replication_configuration_destination = { 115 | region = "eu-west-2" 116 | } 117 | 118 | tags = local.tags 119 | } 120 | 121 | module "efs_default" { 122 | source = "../.." 123 | 124 | name = "${local.name}-default" 125 | 126 | tags = local.tags 127 | } 128 | 129 | module "efs_disabled" { 130 | source = "../.." 131 | 132 | create = false 133 | } 134 | 135 | ################################################################################ 136 | # Supporting Resources 137 | ################################################################################ 138 | 139 | module "vpc" { 140 | source = "terraform-aws-modules/vpc/aws" 141 | version = "~> 6.0" 142 | 143 | name = local.name 144 | cidr = "10.99.0.0/18" 145 | 146 | azs = local.azs 147 | public_subnets = ["10.99.0.0/24", "10.99.1.0/24", "10.99.2.0/24"] 148 | private_subnets = ["10.99.3.0/24", "10.99.4.0/24", "10.99.5.0/24"] 149 | 150 | enable_nat_gateway = false 151 | single_nat_gateway = true 152 | 153 | tags = local.tags 154 | } 155 | 156 | module "kms" { 157 | source = "terraform-aws-modules/kms/aws" 158 | version = "~> 1.0" 159 | 160 | aliases = ["efs/${local.name}"] 161 | description = "EFS customer managed key" 162 | enable_default_policy = true 163 | 164 | # For example use only 165 | deletion_window_in_days = 7 166 | 167 | tags = local.tags 168 | } 169 | -------------------------------------------------------------------------------- /.github/workflows/pre-commit.yml: -------------------------------------------------------------------------------- 1 | name: Pre-Commit 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | - master 8 | 9 | env: 10 | TERRAFORM_DOCS_VERSION: v0.20.0 11 | TFLINT_VERSION: v0.59.1 12 | 13 | jobs: 14 | collectInputs: 15 | name: Collect workflow inputs 16 | runs-on: ubuntu-latest 17 | outputs: 18 | directories: ${{ steps.dirs.outputs.directories }} 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v5 22 | 23 | - name: Get root directories 24 | id: dirs 25 | uses: clowdhaus/terraform-composite-actions/directories@v1.14.0 26 | 27 | preCommitMinVersions: 28 | name: Min TF pre-commit 29 | needs: collectInputs 30 | runs-on: ubuntu-latest 31 | strategy: 32 | matrix: 33 | directory: ${{ fromJson(needs.collectInputs.outputs.directories) }} 34 | steps: 35 | - name: Install rmz 36 | uses: jaxxstorm/action-install-gh-release@v2.1.0 37 | with: 38 | repo: SUPERCILEX/fuc 39 | asset-name: x86_64-unknown-linux-gnu-rmz 40 | rename-to: rmz 41 | chmod: 0755 42 | extension-matching: disable 43 | 44 | # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 45 | - name: Delete unnecessary files 46 | run: | 47 | formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); } 48 | getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); } 49 | 50 | BEFORE=$(getAvailableSpace) 51 | 52 | ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz 53 | rmz -f /opt/hostedtoolcache/CodeQL & 54 | rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk & 55 | rmz -f /opt/hostedtoolcache/PyPy & 56 | rmz -f /opt/hostedtoolcache/Ruby & 57 | rmz -f /opt/hostedtoolcache/go & 58 | 59 | wait 60 | 61 | AFTER=$(getAvailableSpace) 62 | SAVED=$((AFTER-BEFORE)) 63 | echo "=> Saved $(formatByteCount $SAVED)" 64 | 65 | - name: Checkout 66 | uses: actions/checkout@v5 67 | 68 | - name: Terraform min/max versions 69 | id: minMax 70 | uses: clowdhaus/terraform-min-max@v2.1.0 71 | with: 72 | directory: ${{ matrix.directory }} 73 | 74 | - name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }} 75 | # Run only validate pre-commit check on min version supported 76 | if: ${{ matrix.directory != '.' }} 77 | uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 78 | with: 79 | terraform-version: ${{ steps.minMax.outputs.minVersion }} 80 | tflint-version: ${{ env.TFLINT_VERSION }} 81 | args: 'terraform_validate --color=always --show-diff-on-failure --files ${{ matrix.directory }}/*' 82 | 83 | - name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }} 84 | # Run only validate pre-commit check on min version supported 85 | if: ${{ matrix.directory == '.' }} 86 | uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 87 | with: 88 | terraform-version: ${{ steps.minMax.outputs.minVersion }} 89 | tflint-version: ${{ env.TFLINT_VERSION }} 90 | args: 'terraform_validate --color=always --show-diff-on-failure --files $(ls *.tf)' 91 | 92 | preCommitMaxVersion: 93 | name: Max TF pre-commit 94 | runs-on: ubuntu-latest 95 | needs: collectInputs 96 | steps: 97 | - name: Install rmz 98 | uses: jaxxstorm/action-install-gh-release@v2.1.0 99 | with: 100 | repo: SUPERCILEX/fuc 101 | asset-name: x86_64-unknown-linux-gnu-rmz 102 | rename-to: rmz 103 | chmod: 0755 104 | extension-matching: disable 105 | 106 | # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 107 | - name: Delete unnecessary files 108 | run: | 109 | formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); } 110 | getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); } 111 | 112 | BEFORE=$(getAvailableSpace) 113 | 114 | ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz 115 | rmz -f /opt/hostedtoolcache/CodeQL & 116 | rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk & 117 | rmz -f /opt/hostedtoolcache/PyPy & 118 | rmz -f /opt/hostedtoolcache/Ruby & 119 | rmz -f /opt/hostedtoolcache/go & 120 | sudo rmz -f /usr/local/lib/android & 121 | 122 | if [[ ${{ github.repository }} == terraform-aws-modules/terraform-aws-security-group ]]; then 123 | sudo rmz -f /usr/share/dotnet & 124 | sudo rmz -f /usr/local/.ghcup & 125 | sudo apt-get -qq remove -y 'azure-.*' 126 | sudo apt-get -qq remove -y 'cpp-.*' 127 | sudo apt-get -qq remove -y 'dotnet-runtime-.*' 128 | sudo apt-get -qq remove -y 'google-.*' 129 | sudo apt-get -qq remove -y 'libclang-.*' 130 | sudo apt-get -qq remove -y 'libllvm.*' 131 | sudo apt-get -qq remove -y 'llvm-.*' 132 | sudo apt-get -qq remove -y 'mysql-.*' 133 | sudo apt-get -qq remove -y 'postgresql-.*' 134 | sudo apt-get -qq remove -y 'php.*' 135 | sudo apt-get -qq remove -y 'temurin-.*' 136 | sudo apt-get -qq remove -y kubectl firefox mono-devel 137 | sudo apt-get -qq autoremove -y 138 | sudo apt-get -qq clean 139 | fi 140 | 141 | wait 142 | 143 | AFTER=$(getAvailableSpace) 144 | SAVED=$((AFTER-BEFORE)) 145 | echo "=> Saved $(formatByteCount $SAVED)" 146 | 147 | - name: Checkout 148 | uses: actions/checkout@v5 149 | with: 150 | ref: ${{ github.event.pull_request.head.ref }} 151 | repository: ${{github.event.pull_request.head.repo.full_name}} 152 | 153 | - name: Terraform min/max versions 154 | id: minMax 155 | uses: clowdhaus/terraform-min-max@v2.1.0 156 | 157 | - name: Hide template dir 158 | # Special to this repo, we don't want to check this dir 159 | if: ${{ github.repository == 'terraform-aws-modules/terraform-aws-security-group' }} 160 | run: rm -rf modules/_templates 161 | 162 | - name: Pre-commit Terraform ${{ steps.minMax.outputs.maxVersion }} 163 | uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 164 | with: 165 | terraform-version: ${{ steps.minMax.outputs.maxVersion }} 166 | tflint-version: ${{ env.TFLINT_VERSION }} 167 | terraform-docs-version: ${{ env.TERRAFORM_DOCS_VERSION }} 168 | install-hcledit: true 169 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [2.0.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.8.1...v2.0.0) (2025-10-24) 6 | 7 | ### ⚠ BREAKING CHANGES 8 | 9 | * Upgrade AWS provider and min required Terraform version to `6.12` and `1.5.7` respectively (#45) 10 | 11 | ### Features 12 | 13 | * Upgrade AWS provider and min required Terraform version to `6.12` and `1.5.7` respectively ([#45](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/45)) ([91f94a4](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/91f94a4c4b14bf4686f439ca458447bd20e95e99)) 14 | 15 | ## [1.8.1](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.8.0...v1.8.1) (2025-10-21) 16 | 17 | ### Bug Fixes 18 | 19 | * Update CI workflow versions to latest ([#46](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/46)) ([3e5ad26](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/3e5ad26590055103ce409dba1702252048134b90)) 20 | 21 | ## [1.8.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.7.0...v1.8.0) (2025-03-29) 22 | 23 | 24 | ### Features 25 | 26 | * Add `Name` tag to security group created ([#44](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/44)) ([34969f9](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/34969f9d0692ba995aaf1448c941a849ef203007)) 27 | 28 | ## [1.7.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.6.5...v1.7.0) (2025-03-01) 29 | 30 | 31 | ### Features 32 | 33 | * Support `aws_efs_file_system.protection` and `aws_efs_replication_configuration.destination.file_system_id` ([#43](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/43)) ([1dae082](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/1dae0823fa092cf7037e8008d005d67716790ccd)) 34 | 35 | ## [1.6.5](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.6.4...v1.6.5) (2024-11-21) 36 | 37 | 38 | ### Bug Fixes 39 | 40 | * Conditionally create default `NonSecureTransportAccessedViaMountTarget` policy statement ([#35](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/35)) ([7c58eb1](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/7c58eb105f21a3fcdaa081c097528eeba6a8d750)) 41 | 42 | ## [1.6.4](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.6.3...v1.6.4) (2024-10-11) 43 | 44 | 45 | ### Bug Fixes 46 | 47 | * Update CI workflow versions to latest ([#33](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/33)) ([a2bc543](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/a2bc543c5f4d9e973bfc7c07e31e2482400d9686)) 48 | 49 | ## [1.6.3](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.6.2...v1.6.3) (2024-05-12) 50 | 51 | 52 | ### Bug Fixes 53 | 54 | * Bump provider version to include bugfix for `lifecycle_policy` block ([#32](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/32)) ([c1186b9](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/c1186b970ee59ca46f6ce4b795c5f3bd9dc06ee0)) 55 | 56 | ## [1.6.2](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.6.1...v1.6.2) (2024-03-18) 57 | 58 | 59 | ### Bug Fixes 60 | 61 | * Add comment warning about expensive provisioned throughput mode ([#29](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/29)) ([f86d365](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/f86d365fec79acfa0bdf63cc75912645cc472a71)) 62 | 63 | ## [1.6.1](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.6.0...v1.6.1) (2024-03-07) 64 | 65 | 66 | ### Bug Fixes 67 | 68 | * Update CI workflow versions to remove deprecated runtime warnings ([#26](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/26)) ([ada1090](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/ada10907401a9805d6b3358af2b32e6bbf28e3dd)) 69 | 70 | ## [1.6.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.5.0...v1.6.0) (2024-01-21) 71 | 72 | 73 | ### Features 74 | 75 | * Added support in lifecycle_policy with transition_to_archive ([#24](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/24)) ([c6d4be0](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/c6d4be01017517e6d829a3a0cac61a7825b15f72)) 76 | 77 | ## [1.5.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.4.0...v1.5.0) (2024-01-19) 78 | 79 | 80 | ### Features 81 | 82 | * Wrapper for terragrunt ([#23](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/23)) ([5c7ce58](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/5c7ce5828693a1184d6fdad1a0378c4339fcad10)) 83 | 84 | ## [1.4.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.3.1...v1.4.0) (2024-01-12) 85 | 86 | 87 | ### Features 88 | 89 | * Added AccessedViaMountTarget condition for deny_nonsecure_transport ([#21](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/21)) ([543f54c](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/543f54cdf203108106d006ea693463ea463df293)) 90 | 91 | ### [1.3.1](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.3.0...v1.3.1) (2023-11-03) 92 | 93 | 94 | ### Bug Fixes 95 | 96 | * Use `lookup()` on computed resource attribute lookups in `for_each` loop ([#18](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/18)) ([a206e43](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/a206e4397871609dbf80866eb9cddd4b597075c8)) 97 | 98 | ## [1.3.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.2.0...v1.3.0) (2023-09-13) 99 | 100 | 101 | ### Features 102 | 103 | * Add lifecycle create_before_destroy to avoid timeout with security group ([#16](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/16)) ([cab07ba](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/cab07ba2448691c94eb192fbe5a588bcc59dfbdd)) 104 | 105 | ## [1.2.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.1.1...v1.2.0) (2023-06-28) 106 | 107 | 108 | ### Features 109 | 110 | * Added support for elastic throughput mode ([#13](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/13)) ([e247e72](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/e247e72ebaa816cbd46cc508ed2aaab94e03ff74)) 111 | 112 | ### [1.1.1](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.1.0...v1.1.1) (2023-01-17) 113 | 114 | 115 | ### Bug Fixes 116 | 117 | * Allow passing up to the maximum of 2 lifecycle policy statements ([#3](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/3)) ([19f8e7c](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/19f8e7cd5c8c650fbc5a06c00f7e116d95fcdb20)) 118 | 119 | ## [1.1.0](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.0.2...v1.1.0) (2023-01-16) 120 | 121 | 122 | ### Features 123 | 124 | * Allow users to opt out of `NonSecureTransport` policy requirement ([#7](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/7)) ([3f851b1](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/3f851b1ac1efe4a473b697bd287f178e09f838e0)) 125 | 126 | 127 | ### Bug Fixes 128 | 129 | * Use a version for to avoid GitHub API rate limiting on CI workflows ([#6](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/6)) ([269fa7c](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/269fa7c55976e32b7b0c949deef4d729aa0b0cf2)) 130 | 131 | ### [1.0.2](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.0.1...v1.0.2) (2022-12-09) 132 | 133 | 134 | ### Bug Fixes 135 | 136 | * Create backup policy conditionally ([#5](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/5)) ([6154c0c](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/6154c0c6088d7b220f5193dc0f7809f0b7ddc921)) 137 | 138 | ### [1.0.1](https://github.com/terraform-aws-modules/terraform-aws-efs/compare/v1.0.0...v1.0.1) (2022-11-07) 139 | 140 | 141 | ### Bug Fixes 142 | 143 | * Update CI configuration files to use latest version ([#1](https://github.com/terraform-aws-modules/terraform-aws-efs/issues/1)) ([b40028d](https://github.com/terraform-aws-modules/terraform-aws-efs/commit/b40028d9d0139318764c7ef1cdac124e80c0f902)) 144 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "create" { 2 | description = "Determines whether resources will be created (affects all resources)" 3 | type = bool 4 | default = true 5 | } 6 | 7 | variable "name" { 8 | description = "The name of the file system" 9 | type = string 10 | default = "" 11 | } 12 | 13 | variable "region" { 14 | description = "Region where this resource will be managed. Defaults to the Region set in the provider configuration" 15 | type = string 16 | default = null 17 | } 18 | 19 | variable "tags" { 20 | description = "A map of tags to add to all resources" 21 | type = map(string) 22 | default = {} 23 | } 24 | 25 | ################################################################################ 26 | # File System 27 | ################################################################################ 28 | 29 | variable "availability_zone_name" { 30 | description = "The AWS Availability Zone in which to create the file system. Used to create a file system that uses One Zone storage classes" 31 | type = string 32 | default = null 33 | } 34 | 35 | variable "creation_token" { 36 | description = "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" 37 | type = string 38 | default = null 39 | } 40 | 41 | variable "performance_mode" { 42 | description = "The file system performance mode. Can be either `generalPurpose` or `maxIO`. Default is `generalPurpose`" 43 | type = string 44 | default = null 45 | } 46 | 47 | variable "encrypted" { 48 | description = "If `true`, the disk will be encrypted" 49 | type = bool 50 | default = true 51 | } 52 | 53 | variable "kms_key_arn" { 54 | description = "The ARN for the KMS encryption key. When specifying `kms_key_arn`, encrypted needs to be set to `true`" 55 | type = string 56 | default = null 57 | } 58 | 59 | variable "provisioned_throughput_in_mibps" { 60 | description = "The throughput, measured in MiB/s, that you want to provision for the file system. Only applicable with `throughput_mode` set to `provisioned`" 61 | type = number 62 | default = null 63 | } 64 | 65 | variable "throughput_mode" { 66 | description = "Throughput mode for the file system. Defaults to `bursting`. Valid values: `bursting`, `elastic`, and `provisioned`. When using `provisioned`, also set `provisioned_throughput_in_mibps`" 67 | type = string 68 | default = null 69 | } 70 | 71 | variable "lifecycle_policy" { 72 | description = "A file system [lifecycle policy](https://docs.aws.amazon.com/efs/latest/ug/API_LifecyclePolicy.html) object" 73 | type = object({ 74 | transition_to_ia = optional(string) 75 | transition_to_archive = optional(string) 76 | transition_to_primary_storage_class = optional(string) 77 | }) 78 | default = {} 79 | nullable = false 80 | } 81 | 82 | variable "protection" { 83 | description = "A map of file protection configurations" 84 | type = object({ 85 | replication_overwrite = optional(string) 86 | }) 87 | default = null 88 | } 89 | 90 | ################################################################################ 91 | # File System Policy 92 | ################################################################################ 93 | 94 | variable "attach_policy" { 95 | description = "Determines whether a policy is attached to the file system" 96 | type = bool 97 | default = true 98 | } 99 | 100 | variable "bypass_policy_lockout_safety_check" { 101 | description = "A flag to indicate whether to bypass the `aws_efs_file_system_policy` lockout safety check. Defaults to `false`" 102 | type = bool 103 | default = null 104 | } 105 | 106 | variable "source_policy_documents" { 107 | description = "List of IAM policy documents that are merged together into the exported document. Statements must have unique `sid`s" 108 | type = list(string) 109 | default = [] 110 | } 111 | 112 | variable "override_policy_documents" { 113 | description = "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`" 114 | type = list(string) 115 | default = [] 116 | } 117 | 118 | variable "policy_statements" { 119 | description = "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" 120 | type = map(object({ 121 | sid = optional(string) 122 | actions = optional(list(string)) 123 | not_actions = optional(list(string)) 124 | effect = optional(string) 125 | resources = optional(list(string)) 126 | not_resources = optional(list(string)) 127 | principals = optional(list(object({ 128 | type = string 129 | identifiers = list(string) 130 | }))) 131 | not_principals = optional(list(object({ 132 | type = string 133 | identifiers = list(string) 134 | }))) 135 | conditions = optional(list(object({ 136 | test = string 137 | values = list(string) 138 | variable = string 139 | }))) 140 | condition = optional(list(object({ 141 | test = string 142 | values = list(string) 143 | variable = string 144 | }))) 145 | })) 146 | default = null 147 | } 148 | 149 | variable "deny_nonsecure_transport" { 150 | description = "Determines whether `aws:SecureTransport` is required when connecting to elastic file system" 151 | type = bool 152 | default = true 153 | } 154 | 155 | variable "deny_nonsecure_transport_via_mount_target" { 156 | description = "Determines whether to use the common policy option for denying nonsecure transport which allows all AWS principals when accessed via EFS mounted target" 157 | type = bool 158 | default = true 159 | } 160 | 161 | ################################################################################ 162 | # Mount Target(s) 163 | ################################################################################ 164 | 165 | variable "mount_targets" { 166 | description = "A map of mount target definitions to create" 167 | type = map(object({ 168 | ip_address = optional(string) 169 | ip_address_type = optional(string) 170 | ipv6_address = optional(string) 171 | region = optional(string) 172 | security_groups = optional(list(string), []) 173 | subnet_id = string 174 | })) 175 | default = {} 176 | nullable = false 177 | } 178 | 179 | ################################################################################ 180 | # Security Group 181 | ################################################################################ 182 | 183 | variable "create_security_group" { 184 | description = "Determines whether a security group is created" 185 | type = bool 186 | default = true 187 | } 188 | 189 | variable "security_group_name" { 190 | description = "Name to assign to the security group. If omitted, Terraform will assign a random, unique name" 191 | type = string 192 | default = null 193 | } 194 | 195 | variable "security_group_description" { 196 | description = "Security group description. Defaults to Managed by Terraform" 197 | type = string 198 | default = null 199 | } 200 | 201 | variable "security_group_use_name_prefix" { 202 | description = "Determines whether to use a name prefix for the security group. If `true`, the `security_group_name` value will be used as a prefix" 203 | type = bool 204 | default = false 205 | } 206 | 207 | variable "security_group_vpc_id" { 208 | description = "The VPC ID where the security group will be created" 209 | type = string 210 | default = null 211 | } 212 | 213 | variable "security_group_ingress_rules" { 214 | description = "Map of security group ingress rules to add to the security group created" 215 | type = map(object({ 216 | name = optional(string) 217 | 218 | cidr_ipv4 = optional(string) 219 | cidr_ipv6 = optional(string) 220 | description = optional(string) 221 | from_port = optional(number, 2049) 222 | ip_protocol = optional(string, "tcp") 223 | prefix_list_id = optional(string) 224 | referenced_security_group_id = optional(string) 225 | region = optional(string) 226 | tags = optional(map(string), {}) 227 | to_port = optional(number, 2049) 228 | })) 229 | default = {} 230 | nullable = false 231 | } 232 | 233 | variable "security_group_egress_rules" { 234 | description = "Map of security group egress rules to add to the security group created" 235 | type = map(object({ 236 | name = optional(string) 237 | 238 | cidr_ipv4 = optional(string) 239 | cidr_ipv6 = optional(string) 240 | description = optional(string) 241 | from_port = optional(number, 2049) 242 | ip_protocol = optional(string, "tcp") 243 | prefix_list_id = optional(string) 244 | referenced_security_group_id = optional(string) 245 | region = optional(string) 246 | tags = optional(map(string), {}) 247 | to_port = optional(number, 2049) 248 | })) 249 | default = {} 250 | nullable = false 251 | } 252 | 253 | ################################################################################ 254 | # Access Point(s) 255 | ################################################################################ 256 | 257 | variable "access_points" { 258 | description = "A map of access point definitions to create" 259 | type = map(object({ 260 | name = optional(string) 261 | tags = optional(map(string), {}) 262 | posix_user = optional(object({ 263 | gid = number 264 | uid = number 265 | secondary_gids = optional(list(number)) 266 | })) 267 | root_directory = optional(object({ 268 | path = optional(string) 269 | creation_info = optional(object({ 270 | owner_gid = number 271 | owner_uid = number 272 | permissions = string 273 | })) 274 | })) 275 | })) 276 | default = {} 277 | nullable = false 278 | } 279 | 280 | ################################################################################ 281 | # Backup Policy 282 | ################################################################################ 283 | 284 | variable "create_backup_policy" { 285 | description = "Determines whether a backup policy is created" 286 | type = bool 287 | default = true 288 | } 289 | 290 | variable "enable_backup_policy" { 291 | description = "Determines whether a backup policy is `ENABLED` or `DISABLED`" 292 | type = bool 293 | default = true 294 | } 295 | 296 | ################################################################################ 297 | # Replication Configuration 298 | ################################################################################ 299 | 300 | variable "create_replication_configuration" { 301 | description = "Determines whether a replication configuration is created" 302 | type = bool 303 | default = false 304 | } 305 | 306 | variable "replication_configuration_destination" { 307 | description = "A destination configuration block" 308 | type = object({ 309 | availability_zone_name = optional(string) 310 | file_system_id = optional(string) 311 | kms_key_id = optional(string) 312 | region = optional(string) 313 | }) 314 | default = null 315 | } 316 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # File System 3 | ################################################################################ 4 | 5 | resource "aws_efs_file_system" "this" { 6 | count = var.create ? 1 : 0 7 | 8 | availability_zone_name = var.availability_zone_name 9 | creation_token = var.creation_token 10 | performance_mode = var.performance_mode 11 | encrypted = var.encrypted 12 | kms_key_id = var.kms_key_arn 13 | provisioned_throughput_in_mibps = var.provisioned_throughput_in_mibps 14 | throughput_mode = var.throughput_mode 15 | 16 | dynamic "lifecycle_policy" { 17 | for_each = { for k, v in var.lifecycle_policy : k => v if v != null } 18 | 19 | content { 20 | transition_to_ia = lifecycle_policy.key == "transition_to_ia" ? lifecycle_policy.value : null 21 | transition_to_archive = lifecycle_policy.key == "transition_to_archive" ? lifecycle_policy.value : null 22 | transition_to_primary_storage_class = lifecycle_policy.key == "transition_to_primary_storage_class" ? lifecycle_policy.value : null 23 | } 24 | } 25 | 26 | dynamic "protection" { 27 | for_each = var.protection != null ? [var.protection] : [] 28 | content { 29 | replication_overwrite = protection.value.replication_overwrite 30 | } 31 | } 32 | 33 | tags = merge( 34 | var.tags, 35 | { Name = var.name }, 36 | ) 37 | } 38 | 39 | ################################################################################ 40 | # File System Policy 41 | ################################################################################ 42 | 43 | data "aws_iam_policy_document" "policy" { 44 | count = var.create && var.attach_policy ? 1 : 0 45 | 46 | source_policy_documents = var.source_policy_documents 47 | override_policy_documents = var.override_policy_documents 48 | 49 | dynamic "statement" { 50 | for_each = var.policy_statements != null ? var.policy_statements : {} 51 | 52 | content { 53 | sid = coalesce(statement.value.sid, statement.key) 54 | actions = statement.value.actions 55 | not_actions = statement.value.not_actions 56 | effect = statement.value.effect 57 | resources = statement.value.resources != null ? statement.value.resources : [aws_efs_file_system.this[0].arn] 58 | not_resources = statement.value.not_resources 59 | 60 | dynamic "principals" { 61 | for_each = statement.value.principals != null ? statement.value.principals : [] 62 | 63 | content { 64 | type = principals.value.type 65 | identifiers = principals.value.identifiers 66 | } 67 | } 68 | 69 | dynamic "not_principals" { 70 | for_each = statement.value.not_principals != null ? statement.value.not_principals : [] 71 | 72 | content { 73 | type = not_principals.value.type 74 | identifiers = not_principals.value.identifiers 75 | } 76 | } 77 | 78 | dynamic "condition" { 79 | for_each = statement.value.condition != null ? statement.value.condition : [] 80 | 81 | content { 82 | test = condition.value.test 83 | values = condition.value.values 84 | variable = condition.value.variable 85 | } 86 | } 87 | } 88 | } 89 | 90 | dynamic "statement" { 91 | for_each = var.deny_nonsecure_transport ? [1] : [] 92 | 93 | content { 94 | sid = "NonSecureTransport" 95 | effect = "Deny" 96 | actions = ["*"] 97 | resources = [aws_efs_file_system.this[0].arn] 98 | 99 | principals { 100 | type = "AWS" 101 | identifiers = ["*"] 102 | } 103 | 104 | condition { 105 | test = "Bool" 106 | variable = "aws:SecureTransport" 107 | values = ["false"] 108 | } 109 | } 110 | } 111 | 112 | dynamic "statement" { 113 | for_each = var.deny_nonsecure_transport_via_mount_target ? [1] : [] 114 | 115 | content { 116 | sid = "NonSecureTransportAccessedViaMountTarget" 117 | effect = "Allow" 118 | actions = [ 119 | "elasticfilesystem:ClientRootAccess", 120 | "elasticfilesystem:ClientWrite", 121 | "elasticfilesystem:ClientMount" 122 | ] 123 | resources = [aws_efs_file_system.this[0].arn] 124 | 125 | principals { 126 | type = "AWS" 127 | identifiers = ["*"] 128 | } 129 | 130 | condition { 131 | test = "Bool" 132 | variable = "elasticfilesystem:AccessedViaMountTarget" 133 | values = ["true"] 134 | } 135 | } 136 | } 137 | } 138 | 139 | resource "aws_efs_file_system_policy" "this" { 140 | count = var.create && var.attach_policy ? 1 : 0 141 | 142 | file_system_id = aws_efs_file_system.this[0].id 143 | bypass_policy_lockout_safety_check = var.bypass_policy_lockout_safety_check 144 | policy = data.aws_iam_policy_document.policy[0].json 145 | } 146 | 147 | ################################################################################ 148 | # Mount Target(s) 149 | ################################################################################ 150 | 151 | resource "aws_efs_mount_target" "this" { 152 | for_each = { for k, v in var.mount_targets : k => v if var.create } 153 | 154 | file_system_id = aws_efs_file_system.this[0].id 155 | ip_address = each.value.ip_address 156 | ip_address_type = each.value.ip_address_type 157 | ipv6_address = each.value.ipv6_address 158 | region = var.region 159 | security_groups = var.create_security_group ? concat([aws_security_group.this[0].id], each.value.security_groups) : each.value.security_groups 160 | subnet_id = each.value.subnet_id 161 | } 162 | 163 | ################################################################################ 164 | # Security Group 165 | ################################################################################ 166 | 167 | locals { 168 | security_group_name = try(coalesce(var.security_group_name, var.name), "") 169 | 170 | create_security_group = var.create && var.create_security_group && length(var.mount_targets) > 0 171 | } 172 | 173 | resource "aws_security_group" "this" { 174 | count = local.create_security_group ? 1 : 0 175 | 176 | name = var.security_group_use_name_prefix ? null : local.security_group_name 177 | name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null 178 | description = var.security_group_description 179 | 180 | revoke_rules_on_delete = true 181 | vpc_id = var.security_group_vpc_id 182 | 183 | tags = merge( 184 | var.tags, 185 | { Name = local.security_group_name }, 186 | ) 187 | 188 | lifecycle { 189 | create_before_destroy = true 190 | } 191 | } 192 | 193 | resource "aws_vpc_security_group_ingress_rule" "this" { 194 | for_each = { for k, v in var.security_group_ingress_rules : k => v if var.security_group_ingress_rules != null && local.create_security_group } 195 | 196 | region = var.region 197 | 198 | cidr_ipv4 = each.value.cidr_ipv4 199 | cidr_ipv6 = each.value.cidr_ipv6 200 | description = each.value.description 201 | from_port = each.value.from_port 202 | ip_protocol = each.value.ip_protocol 203 | prefix_list_id = each.value.prefix_list_id 204 | referenced_security_group_id = each.value.referenced_security_group_id == "self" ? aws_security_group.this[0].id : each.value.referenced_security_group_id 205 | security_group_id = aws_security_group.this[0].id 206 | tags = merge( 207 | var.tags, 208 | { "Name" = coalesce(each.value.name, "${local.security_group_name}-${each.key}") }, 209 | each.value.tags 210 | ) 211 | to_port = try(coalesce(each.value.to_port, each.value.from_port), null) 212 | } 213 | 214 | resource "aws_vpc_security_group_egress_rule" "this" { 215 | for_each = { for k, v in var.security_group_egress_rules : k => v if var.security_group_egress_rules != null && local.create_security_group } 216 | 217 | region = var.region 218 | 219 | cidr_ipv4 = each.value.cidr_ipv4 220 | cidr_ipv6 = each.value.cidr_ipv6 221 | description = each.value.description 222 | from_port = try(coalesce(each.value.from_port, each.value.to_port), null) 223 | ip_protocol = each.value.ip_protocol 224 | prefix_list_id = each.value.prefix_list_id 225 | referenced_security_group_id = each.value.referenced_security_group_id == "self" ? aws_security_group.this[0].id : each.value.referenced_security_group_id 226 | security_group_id = aws_security_group.this[0].id 227 | tags = merge( 228 | var.tags, 229 | { "Name" = coalesce(each.value.name, "${local.security_group_name}-${each.key}") }, 230 | each.value.tags 231 | ) 232 | to_port = each.value.to_port 233 | } 234 | 235 | ################################################################################ 236 | # Access Point(s) 237 | ################################################################################ 238 | 239 | resource "aws_efs_access_point" "this" { 240 | for_each = { for k, v in var.access_points : k => v if var.create } 241 | 242 | file_system_id = aws_efs_file_system.this[0].id 243 | 244 | dynamic "posix_user" { 245 | for_each = each.value.posix_user != null ? [each.value.posix_user] : [] 246 | 247 | content { 248 | gid = posix_user.value.gid 249 | uid = posix_user.value.uid 250 | secondary_gids = posix_user.value.secondary_gids 251 | } 252 | } 253 | 254 | dynamic "root_directory" { 255 | for_each = each.value.root_directory != null ? [each.value.root_directory] : [] 256 | 257 | content { 258 | path = root_directory.value.path 259 | 260 | dynamic "creation_info" { 261 | for_each = root_directory.value.creation_info != null ? [root_directory.value.creation_info] : [] 262 | 263 | content { 264 | owner_gid = creation_info.value.owner_gid 265 | owner_uid = creation_info.value.owner_uid 266 | permissions = creation_info.value.permissions 267 | } 268 | } 269 | } 270 | } 271 | 272 | tags = merge( 273 | var.tags, 274 | each.value.tags, 275 | { Name = each.value.name != null ? each.value.name : each.key }, 276 | ) 277 | } 278 | 279 | ################################################################################ 280 | # Backup Policy 281 | ################################################################################ 282 | 283 | resource "aws_efs_backup_policy" "this" { 284 | count = var.create && var.create_backup_policy ? 1 : 0 285 | 286 | file_system_id = aws_efs_file_system.this[0].id 287 | 288 | backup_policy { 289 | status = var.enable_backup_policy ? "ENABLED" : "DISABLED" 290 | } 291 | } 292 | 293 | ################################################################################ 294 | # Replication Configuration 295 | ################################################################################ 296 | 297 | resource "aws_efs_replication_configuration" "this" { 298 | count = var.create && var.create_replication_configuration ? 1 : 0 299 | 300 | source_file_system_id = aws_efs_file_system.this[0].id 301 | 302 | dynamic "destination" { 303 | for_each = var.replication_configuration_destination != null ? [var.replication_configuration_destination] : [] 304 | 305 | content { 306 | availability_zone_name = destination.value.availability_zone_name 307 | file_system_id = destination.value.file_system_id 308 | kms_key_id = destination.value.kms_key_id 309 | region = destination.value.region 310 | } 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS EFS Terraform module 2 | 3 | Terraform module which creates AWS EFS (elastic file system) resources. 4 | 5 | [](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) 6 | 7 | ## Usage 8 | 9 | See [`examples`](https://github.com/terraform-aws-modules/terraform-aws-efs/tree/master/examples) directory for working examples to reference: 10 | 11 | ```hcl 12 | module "efs" { 13 | source = "terraform-aws-modules/efs/aws" 14 | 15 | # File system 16 | name = "example" 17 | creation_token = "example-token" 18 | encrypted = true 19 | kms_key_arn = "arn:aws:kms:eu-west-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" 20 | 21 | # performance_mode = "maxIO" 22 | # NB! PROVISIONED TROUGHPUT MODE WITH 256 MIBPS IS EXPENSIVE ~$1500/month 23 | # throughput_mode = "provisioned" 24 | # provisioned_throughput_in_mibps = 256 25 | 26 | lifecycle_policy = { 27 | transition_to_ia = "AFTER_30_DAYS" 28 | } 29 | 30 | # File system policy 31 | attach_policy = true 32 | bypass_policy_lockout_safety_check = false 33 | policy_statements = [ 34 | { 35 | sid = "Example" 36 | actions = ["elasticfilesystem:ClientMount"] 37 | principals = [ 38 | { 39 | type = "AWS" 40 | identifiers = ["arn:aws:iam::111122223333:role/EfsReadOnly"] 41 | } 42 | ] 43 | } 44 | ] 45 | 46 | # Mount targets / security group 47 | mount_targets = { 48 | "eu-west-1a" = { 49 | subnet_id = "subnet-abcde012" 50 | } 51 | "eu-west-1b" = { 52 | subnet_id = "subnet-bcde012a" 53 | } 54 | "eu-west-1c" = { 55 | subnet_id = "subnet-fghi345a" 56 | } 57 | } 58 | security_group_description = "Example EFS security group" 59 | security_group_vpc_id = "vpc-1234556abcdef" 60 | security_group_ingress_rules = { 61 | vpc_1 = { 62 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 63 | description = "NFS ingress from VPC private subnets" 64 | cidr_ipv4 = "10.99.3.0/24" 65 | } 66 | vpc_2 = { 67 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 68 | description = "NFS ingress from VPC private subnets" 69 | cidr_ipv4 = "10.99.4.0/24" 70 | } 71 | vpc_3 = { 72 | # relying on the defaults provided for EFS/NFS (2049/TCP + ingress) 73 | description = "NFS ingress from VPC private subnets" 74 | cidr_ipv4 = "10.99.5.0/24" 75 | } 76 | } 77 | 78 | # Access point(s) 79 | access_points = { 80 | posix_example = { 81 | name = "posix-example" 82 | posix_user = { 83 | gid = 1001 84 | uid = 1001 85 | secondary_gids = [1002] 86 | } 87 | 88 | tags = { 89 | Additionl = "yes" 90 | } 91 | } 92 | root_example = { 93 | root_directory = { 94 | path = "/example" 95 | creation_info = { 96 | owner_gid = 1001 97 | owner_uid = 1001 98 | permissions = "755" 99 | } 100 | } 101 | } 102 | } 103 | 104 | # Backup policy 105 | enable_backup_policy = true 106 | 107 | # Replication configuration 108 | create_replication_configuration = true 109 | replication_configuration_destination = { 110 | region = "eu-west-2" 111 | } 112 | 113 | tags = { 114 | Terraform = "true" 115 | Environment = "dev" 116 | } 117 | } 118 | ``` 119 | 120 | ## Examples 121 | 122 | Examples codified under the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-efs/tree/master/examples) are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module. If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you! 123 | 124 | - [Complete](https://github.com/terraform-aws-modules/terraform-aws-efs/tree/master/examples/complete) 125 | 126 | 127 | ## Requirements 128 | 129 | | Name | Version | 130 | |------|---------| 131 | | [terraform](#requirement\_terraform) | >= 1.5.7 | 132 | | [aws](#requirement\_aws) | >= 6.12 | 133 | 134 | ## Providers 135 | 136 | | Name | Version | 137 | |------|---------| 138 | | [aws](#provider\_aws) | >= 6.12 | 139 | 140 | ## Modules 141 | 142 | No modules. 143 | 144 | ## Resources 145 | 146 | | Name | Type | 147 | |------|------| 148 | | [aws_efs_access_point.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_access_point) | resource | 149 | | [aws_efs_backup_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_backup_policy) | resource | 150 | | [aws_efs_file_system.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_file_system) | resource | 151 | | [aws_efs_file_system_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_file_system_policy) | resource | 152 | | [aws_efs_mount_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_mount_target) | resource | 153 | | [aws_efs_replication_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_replication_configuration) | resource | 154 | | [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | 155 | | [aws_vpc_security_group_egress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource | 156 | | [aws_vpc_security_group_ingress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | 157 | | [aws_iam_policy_document.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | 158 | 159 | ## Inputs 160 | 161 | | Name | Description | Type | Default | Required | 162 | |------|-------------|------|---------|:--------:| 163 | | [access\_points](#input\_access\_points) | A map of access point definitions to create |
map(object({
name = optional(string)
tags = optional(map(string), {})
posix_user = optional(object({
gid = number
uid = number
secondary_gids = optional(list(number))
}))
root_directory = optional(object({
path = optional(string)
creation_info = optional(object({
owner_gid = number
owner_uid = number
permissions = string
}))
}))
})) | `{}` | no |
164 | | [attach\_policy](#input\_attach\_policy) | Determines whether a policy is attached to the file system | `bool` | `true` | no |
165 | | [availability\_zone\_name](#input\_availability\_zone\_name) | The AWS Availability Zone in which to create the file system. Used to create a file system that uses One Zone storage classes | `string` | `null` | no |
166 | | [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. Defaults to `false` | `bool` | `null` | no |
167 | | [create](#input\_create) | Determines whether resources will be created (affects all resources) | `bool` | `true` | no |
168 | | [create\_backup\_policy](#input\_create\_backup\_policy) | Determines whether a backup policy is created | `bool` | `true` | no |
169 | | [create\_replication\_configuration](#input\_create\_replication\_configuration) | Determines whether a replication configuration is created | `bool` | `false` | no |
170 | | [create\_security\_group](#input\_create\_security\_group) | Determines whether a security group is created | `bool` | `true` | no |
171 | | [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 |
172 | | [deny\_nonsecure\_transport](#input\_deny\_nonsecure\_transport) | Determines whether `aws:SecureTransport` is required when connecting to elastic file system | `bool` | `true` | no |
173 | | [deny\_nonsecure\_transport\_via\_mount\_target](#input\_deny\_nonsecure\_transport\_via\_mount\_target) | Determines whether to use the common policy option for denying nonsecure transport which allows all AWS principals when accessed via EFS mounted target | `bool` | `true` | no |
174 | | [enable\_backup\_policy](#input\_enable\_backup\_policy) | Determines whether a backup policy is `ENABLED` or `DISABLED` | `bool` | `true` | no |
175 | | [encrypted](#input\_encrypted) | If `true`, the disk will be encrypted | `bool` | `true` | no |
176 | | [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 |
177 | | [lifecycle\_policy](#input\_lifecycle\_policy) | A file system [lifecycle policy](https://docs.aws.amazon.com/efs/latest/ug/API_LifecyclePolicy.html) object | object({
transition_to_ia = optional(string)
transition_to_archive = optional(string)
transition_to_primary_storage_class = optional(string)
}) | `{}` | no |
178 | | [mount\_targets](#input\_mount\_targets) | A map of mount target definitions to create | map(object({
ip_address = optional(string)
ip_address_type = optional(string)
ipv6_address = optional(string)
region = optional(string)
security_groups = optional(list(string), [])
subnet_id = string
})) | `{}` | no |
179 | | [name](#input\_name) | The name of the file system | `string` | `""` | no |
180 | | [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 |
181 | | [performance\_mode](#input\_performance\_mode) | The file system performance mode. Can be either `generalPurpose` or `maxIO`. Default is `generalPurpose` | `string` | `null` | no |
182 | | [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 | map(object({
sid = optional(string)
actions = optional(list(string))
not_actions = optional(list(string))
effect = optional(string)
resources = optional(list(string))
not_resources = optional(list(string))
principals = optional(list(object({
type = string
identifiers = list(string)
})))
not_principals = optional(list(object({
type = string
identifiers = list(string)
})))
conditions = optional(list(object({
test = string
values = list(string)
variable = string
})))
condition = optional(list(object({
test = string
values = list(string)
variable = string
})))
})) | `null` | no |
183 | | [protection](#input\_protection) | A map of file protection configurations | object({
replication_overwrite = optional(string)
}) | `null` | no |
184 | | [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 |
185 | | [region](#input\_region) | Region where this resource will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no |
186 | | [replication\_configuration\_destination](#input\_replication\_configuration\_destination) | A destination configuration block | object({
availability_zone_name = optional(string)
file_system_id = optional(string)
kms_key_id = optional(string)
region = optional(string)
}) | `null` | no |
187 | | [security\_group\_description](#input\_security\_group\_description) | Security group description. Defaults to Managed by Terraform | `string` | `null` | no |
188 | | [security\_group\_egress\_rules](#input\_security\_group\_egress\_rules) | Map of security group egress rules to add to the security group created | map(object({
name = optional(string)
cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(number, 2049)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
region = optional(string)
tags = optional(map(string), {})
to_port = optional(number, 2049)
})) | `{}` | no |
189 | | [security\_group\_ingress\_rules](#input\_security\_group\_ingress\_rules) | Map of security group ingress rules to add to the security group created | map(object({
name = optional(string)
cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(number, 2049)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
region = optional(string)
tags = optional(map(string), {})
to_port = optional(number, 2049)
})) | `{}` | no |
190 | | [security\_group\_name](#input\_security\_group\_name) | Name to assign to the security group. If omitted, Terraform will assign a random, unique name | `string` | `null` | no |
191 | | [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether to use a name prefix for the security group. If `true`, the `security_group_name` value will be used as a prefix | `bool` | `false` | no |
192 | | [security\_group\_vpc\_id](#input\_security\_group\_vpc\_id) | The VPC ID where the security group will be created | `string` | `null` | no |
193 | | [source\_policy\_documents](#input\_source\_policy\_documents) | List of IAM policy documents that are merged together into the exported document. Statements must have unique `sid`s | `list(string)` | `[]` | no |
194 | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
195 | | [throughput\_mode](#input\_throughput\_mode) | Throughput mode for the file system. Defaults to `bursting`. Valid values: `bursting`, `elastic`, and `provisioned`. When using `provisioned`, also set `provisioned_throughput_in_mibps` | `string` | `null` | no |
196 |
197 | ## Outputs
198 |
199 | | Name | Description |
200 | |------|-------------|
201 | | [access\_points](#output\_access\_points) | Map of access points created and their attributes |
202 | | [arn](#output\_arn) | Amazon Resource Name of the file system |
203 | | [dns\_name](#output\_dns\_name) | The DNS name for the filesystem per [documented convention](http://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html) |
204 | | [id](#output\_id) | The ID that identifies the file system (e.g., `fs-ccfc0d65`) |
205 | | [mount\_targets](#output\_mount\_targets) | Map of mount targets created and their attributes |
206 | | [replication\_configuration\_destination\_file\_system\_id](#output\_replication\_configuration\_destination\_file\_system\_id) | The file system ID of the replica |
207 | | [security\_group\_arn](#output\_security\_group\_arn) | ARN of the security group |
208 | | [security\_group\_id](#output\_security\_group\_id) | ID of the security group |
209 | | [size\_in\_bytes](#output\_size\_in\_bytes) | The latest known metered size (in bytes) of data stored in the file system, the value is not the exact size that the file system was at any point in time |
210 |
211 |
212 | ## License
213 |
214 | Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-efs/blob/master/LICENSE).
215 |
--------------------------------------------------------------------------------