├── examples ├── complete │ ├── variables.tf │ ├── versions.tf │ ├── main.tf │ └── outputs.tf └── README.md ├── wrappers ├── outputs.tf ├── versions.tf ├── variables.tf ├── README.md └── main.tf ├── versions.tf ├── .editorconfig ├── aws_cloudwatch_observability.tf ├── .gitignore ├── .github └── workflows │ ├── lock.yml │ ├── release.yml │ ├── stale-actions.yaml │ ├── pr-title.yml │ └── pre-commit.yml ├── .releaserc.json ├── .pre-commit-config.yaml ├── aws_privateca_issuer.tf ├── external_dns.tf ├── cert_manager.tf ├── mountpoint_s3_csi.tf ├── amazon_managed_service_prometheus.tf ├── aws_node_termination_handler.tf ├── aws_fsx_lustre_csi.tf ├── pganalyze.tf ├── velero.tf ├── aws_efs_csi.tf ├── cluster_autoscaler.tf ├── aws_gateway_controller.tf ├── aws_vpc_cni.tf ├── external_secrets.tf ├── outputs.tf ├── aws_ebs_csi.tf ├── aws_appmesh.tf ├── main.tf ├── LICENSE ├── aws_lb_controller.tf ├── CHANGELOG.md └── variables.tf /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.2" 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.2" 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.2" 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 | -------------------------------------------------------------------------------- /aws_cloudwatch_observability.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # AWS CloudWatch Observability 3 | ################################################################################ 4 | 5 | resource "aws_iam_role_policy_attachment" "aws_cloudwatch_observability" { 6 | for_each = { for k, v in { 7 | CloudWatchAgentServerPolicy = "arn:${local.partition}:iam::aws:policy/CloudWatchAgentServerPolicy" 8 | AWSXrayWriteOnlyAccess = "arn:${local.partition}:iam::aws:policy/AWSXrayWriteOnlyAccess" 9 | } : k => v if var.create && var.attach_aws_cloudwatch_observability_policy } 10 | 11 | role = aws_iam_role.this[0].name 12 | policy_arn = each.value 13 | } 14 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /aws_privateca_issuer.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # AWS Private CA Issuer 3 | ################################################################################ 4 | 5 | data "aws_iam_policy_document" "aws_privateca_issuer" { 6 | count = var.create && var.attach_aws_privateca_issuer_policy ? 1 : 0 7 | 8 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 9 | override_policy_documents = var.override_policy_documents 10 | 11 | statement { 12 | actions = [ 13 | "acm-pca:DescribeCertificateAuthority", 14 | "acm-pca:GetCertificate", 15 | "acm-pca:IssueCertificate", 16 | ] 17 | 18 | resources = var.aws_privateca_issuer_acmca_arns 19 | } 20 | } 21 | 22 | locals { 23 | aws_privateca_issuer_policy_name = coalesce(var.aws_privateca_issuer_policy_name, "${var.policy_name_prefix}PrivateCAIssuer") 24 | } 25 | 26 | resource "aws_iam_policy" "aws_privateca_issuer" { 27 | count = var.create && var.attach_aws_privateca_issuer_policy ? 1 : 0 28 | 29 | name = var.use_name_prefix ? null : local.aws_privateca_issuer_policy_name 30 | name_prefix = var.use_name_prefix ? "${local.aws_privateca_issuer_policy_name}-" : null 31 | path = var.path 32 | description = "Permissions for AWS Private CA Issuer" 33 | policy = data.aws_iam_policy_document.aws_privateca_issuer[0].json 34 | 35 | tags = var.tags 36 | } 37 | 38 | resource "aws_iam_role_policy_attachment" "aws_privateca_issuer" { 39 | count = var.create && var.attach_aws_privateca_issuer_policy ? 1 : 0 40 | 41 | role = aws_iam_role.this[0].name 42 | policy_arn = aws_iam_policy.aws_privateca_issuer[0].arn 43 | } 44 | -------------------------------------------------------------------------------- /external_dns.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # External DNS Policy 3 | ################################################################################ 4 | 5 | # https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md#iam-policy 6 | 7 | data "aws_iam_policy_document" "external_dns" { 8 | count = var.create && var.attach_external_dns_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = ["route53:ChangeResourceRecordSets"] 15 | resources = var.external_dns_hosted_zone_arns 16 | } 17 | 18 | statement { 19 | actions = [ 20 | "route53:ListHostedZones", 21 | "route53:ListResourceRecordSets", 22 | "route53:ListTagsForResource", 23 | "route53:ListTagsForResources", 24 | ] 25 | 26 | resources = ["*"] 27 | } 28 | } 29 | 30 | locals { 31 | external_dns_policy_name = coalesce(var.external_dns_policy_name, "${var.policy_name_prefix}ExternalDNS") 32 | } 33 | 34 | resource "aws_iam_policy" "external_dns" { 35 | count = var.create && var.attach_external_dns_policy ? 1 : 0 36 | 37 | name = var.use_name_prefix ? null : local.external_dns_policy_name 38 | name_prefix = var.use_name_prefix ? "${local.external_dns_policy_name}-" : null 39 | path = var.path 40 | description = "Permissions for External DNS" 41 | policy = data.aws_iam_policy_document.external_dns[0].json 42 | 43 | tags = var.tags 44 | } 45 | 46 | resource "aws_iam_role_policy_attachment" "external_dns" { 47 | count = var.create && var.attach_external_dns_policy ? 1 : 0 48 | 49 | role = aws_iam_role.this[0].name 50 | policy_arn = aws_iam_policy.external_dns[0].arn 51 | } 52 | -------------------------------------------------------------------------------- /cert_manager.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Cert Manager Policy 3 | ################################################################################ 4 | 5 | # https://cert-manager.io/docs/configuration/acme/dns01/route53/#set-up-an-iam-role 6 | 7 | data "aws_iam_policy_document" "cert_manager" { 8 | count = var.create && var.attach_cert_manager_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = ["route53:GetChange"] 15 | resources = ["arn:${local.partition}:route53:::change/*"] 16 | } 17 | 18 | statement { 19 | actions = [ 20 | "route53:ChangeResourceRecordSets", 21 | "route53:ListResourceRecordSets" 22 | ] 23 | 24 | resources = var.cert_manager_hosted_zone_arns 25 | } 26 | 27 | statement { 28 | actions = ["route53:ListHostedZonesByName"] 29 | resources = ["*"] 30 | } 31 | } 32 | 33 | locals { 34 | cert_manager_policy_name = coalesce(var.cert_manager_policy_name, "${var.policy_name_prefix}CertManager") 35 | } 36 | 37 | resource "aws_iam_policy" "cert_manager" { 38 | count = var.create && var.attach_cert_manager_policy ? 1 : 0 39 | 40 | name = var.use_name_prefix ? null : local.cert_manager_policy_name 41 | name_prefix = var.use_name_prefix ? "${local.cert_manager_policy_name}-" : null 42 | path = var.path 43 | description = "Permissions for Cert Manager" 44 | policy = data.aws_iam_policy_document.cert_manager[0].json 45 | 46 | tags = var.tags 47 | } 48 | 49 | resource "aws_iam_role_policy_attachment" "cert_manager" { 50 | count = var.create && var.attach_cert_manager_policy ? 1 : 0 51 | 52 | role = aws_iam_role.this[0].name 53 | policy_arn = aws_iam_policy.cert_manager[0].arn 54 | } 55 | -------------------------------------------------------------------------------- /mountpoint_s3_csi.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Mountpoint S3 CSI Driver Policy 3 | ################################################################################ 4 | 5 | # https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md#iam-permissions 6 | 7 | data "aws_iam_policy_document" "mountpoint_s3_csi" { 8 | count = var.create && var.attach_mountpoint_s3_csi_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | sid = "MountpointFullBucketAccess" 15 | actions = ["s3:ListBucket"] 16 | resources = coalescelist(var.mountpoint_s3_csi_bucket_arns, ["arn:${local.partition}:s3:::*"]) 17 | } 18 | 19 | statement { 20 | sid = "MountpointFullObjectAccess" 21 | actions = [ 22 | "s3:GetObject", 23 | "s3:PutObject", 24 | "s3:AbortMultipartUpload", 25 | "s3:DeleteObject" 26 | ] 27 | resources = var.mountpoint_s3_csi_bucket_path_arns 28 | } 29 | } 30 | 31 | locals { 32 | mountpoint_s3_csi_policy_name = coalesce(var.mountpoint_s3_csi_policy_name, "${var.policy_name_prefix}MountpointS3_CSI") 33 | } 34 | 35 | resource "aws_iam_policy" "mountpoint_s3_csi" { 36 | count = var.create && var.attach_mountpoint_s3_csi_policy ? 1 : 0 37 | 38 | name = var.use_name_prefix ? null : local.mountpoint_s3_csi_policy_name 39 | name_prefix = var.use_name_prefix ? "${local.mountpoint_s3_csi_policy_name}-" : null 40 | path = var.path 41 | description = "Permissions for Mountpoint S3 CSI Driver" 42 | policy = data.aws_iam_policy_document.mountpoint_s3_csi[0].json 43 | 44 | tags = var.tags 45 | } 46 | 47 | resource "aws_iam_role_policy_attachment" "mountpoint_s3_csi" { 48 | count = var.create && var.attach_mountpoint_s3_csi_policy ? 1 : 0 49 | 50 | role = aws_iam_role.this[0].name 51 | policy_arn = aws_iam_policy.mountpoint_s3_csi[0].arn 52 | } 53 | -------------------------------------------------------------------------------- /amazon_managed_service_prometheus.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Amazon Managed Service for Prometheus Policy 3 | ################################################################################ 4 | 5 | locals { 6 | amazon_managed_service_prometheus_policy_name = coalesce(var.amazon_managed_service_prometheus_policy_name, "${var.policy_name_prefix}ManagedServiceForPrometheus") 7 | } 8 | 9 | # https://docs.aws.amazon.com/prometheus/latest/userguide/set-up-irsa.html 10 | data "aws_iam_policy_document" "amazon_managed_service_prometheus" { 11 | count = var.create && var.attach_amazon_managed_service_prometheus_policy ? 1 : 0 12 | 13 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 14 | override_policy_documents = var.override_policy_documents 15 | 16 | statement { 17 | actions = [ 18 | "aps:RemoteWrite", 19 | "aps:QueryMetrics", 20 | "aps:GetSeries", 21 | "aps:GetLabels", 22 | "aps:GetMetricMetadata", 23 | ] 24 | 25 | resources = var.amazon_managed_service_prometheus_workspace_arns 26 | } 27 | } 28 | 29 | resource "aws_iam_policy" "amazon_managed_service_prometheus" { 30 | count = var.create && var.attach_amazon_managed_service_prometheus_policy ? 1 : 0 31 | 32 | name = var.use_name_prefix ? null : local.amazon_managed_service_prometheus_policy_name 33 | name_prefix = var.use_name_prefix ? "${local.amazon_managed_service_prometheus_policy_name}-" : null 34 | path = var.path 35 | description = "Permissions for Amazon Managed Service for Prometheus" 36 | policy = data.aws_iam_policy_document.amazon_managed_service_prometheus[0].json 37 | 38 | tags = var.tags 39 | } 40 | 41 | resource "aws_iam_role_policy_attachment" "amazon_managed_service_prometheus" { 42 | count = var.create && var.attach_amazon_managed_service_prometheus_policy ? 1 : 0 43 | 44 | role = aws_iam_role.this[0].name 45 | policy_arn = aws_iam_policy.amazon_managed_service_prometheus[0].arn 46 | } 47 | -------------------------------------------------------------------------------- /aws_node_termination_handler.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Node Termination Handler Policy 3 | ################################################################################ 4 | 5 | # https://github.com/aws/aws-node-termination-handler#5-create-an-iam-role-for-the-pods 6 | 7 | data "aws_iam_policy_document" "node_termination_handler" { 8 | count = var.create && var.attach_aws_node_termination_handler_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = [ 15 | "autoscaling:CompleteLifecycleAction", 16 | "autoscaling:DescribeAutoScalingInstances", 17 | "autoscaling:DescribeTags", 18 | "ec2:DescribeInstances", 19 | ] 20 | 21 | resources = ["*"] 22 | } 23 | 24 | statement { 25 | actions = [ 26 | "sqs:DeleteMessage", 27 | "sqs:ReceiveMessage", 28 | ] 29 | 30 | resources = var.aws_node_termination_handler_sqs_queue_arns 31 | } 32 | } 33 | 34 | locals { 35 | aws_node_termination_handler_policy_name = coalesce(var.aws_node_termination_handler_policy_name, "${var.policy_name_prefix}NodeTerminationHandler") 36 | } 37 | 38 | resource "aws_iam_policy" "node_termination_handler" { 39 | count = var.create && var.attach_aws_node_termination_handler_policy ? 1 : 0 40 | 41 | name = var.use_name_prefix ? null : local.aws_node_termination_handler_policy_name 42 | name_prefix = var.use_name_prefix ? "${local.aws_node_termination_handler_policy_name}-" : null 43 | path = var.path 44 | description = "Permissions for Node Termination Handler" 45 | policy = data.aws_iam_policy_document.node_termination_handler[0].json 46 | 47 | tags = var.tags 48 | } 49 | 50 | resource "aws_iam_role_policy_attachment" "node_termination_handler" { 51 | count = var.create && var.attach_aws_node_termination_handler_policy ? 1 : 0 52 | 53 | role = aws_iam_role.this[0].name 54 | policy_arn = aws_iam_policy.node_termination_handler[0].arn 55 | } 56 | -------------------------------------------------------------------------------- /aws_fsx_lustre_csi.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # FSx for Lustre CSI Driver Policy 3 | ################################################################################ 4 | 5 | # https://github.com/kubernetes-sigs/aws-fsx-csi-driver/blob/master/docs/install.md 6 | 7 | data "aws_iam_policy_document" "fsx_lustre_csi" { 8 | count = var.create && var.attach_aws_fsx_lustre_csi_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = [ 15 | "iam:CreateServiceLinkedRole", 16 | "iam:AttachRolePolicy", 17 | "iam:PutRolePolicy" 18 | ] 19 | resources = coalescelist(var.aws_fsx_lustre_csi_service_role_arns, ["arn:${local.partition}:iam::*:role/aws-service-role/s3.data-source.lustre.fsx.amazonaws.com/*"]) 20 | } 21 | 22 | statement { 23 | actions = ["iam:CreateServiceLinkedRole"] 24 | resources = ["*"] 25 | 26 | condition { 27 | test = "StringLike" 28 | variable = "iam:AWSServiceName" 29 | values = ["fsx.amazonaws.com"] 30 | } 31 | } 32 | 33 | statement { 34 | actions = [ 35 | "s3:ListBucket", 36 | "fsx:CreateFileSystem", 37 | "fsx:DeleteFileSystem", 38 | "fsx:DescribeFileSystems", 39 | "fsx:TagResource", 40 | "fsx:UpdateFileSystem", 41 | ] 42 | resources = ["*"] 43 | } 44 | } 45 | 46 | locals { 47 | aws_fsx_lustre_csi_policy_name = coalesce(var.aws_fsx_lustre_csi_policy_name, "${var.policy_name_prefix}FSxForLustre_CSI") 48 | } 49 | 50 | resource "aws_iam_policy" "fsx_lustre_csi" { 51 | count = var.create && var.attach_aws_fsx_lustre_csi_policy ? 1 : 0 52 | 53 | name = var.use_name_prefix ? null : local.aws_fsx_lustre_csi_policy_name 54 | name_prefix = var.use_name_prefix ? "${local.aws_fsx_lustre_csi_policy_name}-" : null 55 | path = var.path 56 | description = "Permissions to manage FSx Lustre volumes via the container storage interface (CSI) driver" 57 | policy = data.aws_iam_policy_document.fsx_lustre_csi[0].json 58 | 59 | tags = var.tags 60 | } 61 | 62 | resource "aws_iam_role_policy_attachment" "fsx_lustre_csi" { 63 | count = var.create && var.attach_aws_fsx_lustre_csi_policy ? 1 : 0 64 | 65 | role = aws_iam_role.this[0].name 66 | policy_arn = aws_iam_policy.fsx_lustre_csi[0].arn 67 | } 68 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /pganalyze.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # PGAnalyze Policy 3 | ################################################################################ 4 | 5 | # https://pganalyze.com/docs/install/amazon_rds/03_install_collector_eks#set-up-iam-policy 6 | 7 | data "aws_iam_policy_document" "pganalyze" { 8 | count = var.create && var.attach_pganalyze_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | sid = "CloudwatchGetMetrics" 15 | actions = ["cloudwatch:GetMetricStatistics"] 16 | resources = ["*"] 17 | } 18 | 19 | statement { 20 | sid = "CloudwatchLogEvents" 21 | actions = ["logs:GetLogEvents"] 22 | resources = ["arn:${local.partition}:logs:${local.region}:${local.account_id}:log-group:RDSOSMetrics:log-stream:*"] 23 | } 24 | 25 | statement { 26 | sid = "RDSDescribeParameters" 27 | actions = ["rds:DescribeDBParameters"] 28 | resources = ["arn:${local.partition}:rds:${local.region}:${local.account_id}:pg:*"] 29 | } 30 | 31 | statement { 32 | sid = "RDSInstanceDescribe" 33 | actions = [ 34 | "rds:DescribeDBInstances", 35 | "rds:DownloadDBLogFilePortion", 36 | "rds:DescribeDBLogFiles", 37 | ] 38 | resources = ["arn:${local.partition}:rds:${local.region}:${local.account_id}:db:*"] 39 | } 40 | 41 | statement { 42 | sid = "RDSClusterDescribe" 43 | actions = ["rds:DescribeDBClusters"] 44 | resources = ["arn:${local.partition}:rds:${local.region}:${local.account_id}:cluster:*"] 45 | } 46 | } 47 | 48 | locals { 49 | pganalyze_policy_name = coalesce(var.pganalyze_policy_name, "${var.policy_name_prefix}PGAnalyze") 50 | } 51 | 52 | resource "aws_iam_policy" "pganalyze" { 53 | count = var.create && var.attach_pganalyze_policy ? 1 : 0 54 | 55 | name = var.use_name_prefix ? null : local.pganalyze_policy_name 56 | name_prefix = var.use_name_prefix ? "${local.pganalyze_policy_name}-" : null 57 | path = var.path 58 | description = "Permissions for PGAnalyze" 59 | policy = data.aws_iam_policy_document.pganalyze[0].json 60 | 61 | tags = var.tags 62 | } 63 | 64 | resource "aws_iam_role_policy_attachment" "pganalyze" { 65 | count = var.create && var.attach_pganalyze_policy ? 1 : 0 66 | 67 | role = aws_iam_role.this[0].name 68 | policy_arn = aws_iam_policy.pganalyze[0].arn 69 | } 70 | -------------------------------------------------------------------------------- /velero.tf: -------------------------------------------------------------------------------- 1 | 2 | ################################################################################ 3 | # Velero Policy 4 | ################################################################################ 5 | 6 | # https://github.com/vmware-tanzu/velero-plugin-for-aws#set-permissions-for-velero 7 | 8 | data "aws_iam_policy_document" "velero" { 9 | count = var.create && var.attach_velero_policy ? 1 : 0 10 | 11 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 12 | override_policy_documents = var.override_policy_documents 13 | 14 | statement { 15 | sid = "Ec2ReadWrite" 16 | actions = [ 17 | "ec2:DescribeVolumes", 18 | "ec2:DescribeSnapshots", 19 | "ec2:CreateTags", 20 | "ec2:CreateVolume", 21 | "ec2:CreateSnapshot", 22 | "ec2:DeleteSnapshot", 23 | ] 24 | resources = ["*"] 25 | } 26 | 27 | statement { 28 | sid = "S3ReadWrite" 29 | actions = [ 30 | "s3:GetObject", 31 | "s3:DeleteObject", 32 | "s3:PutObject", 33 | "s3:PutObjectTagging", 34 | "s3:AbortMultipartUpload", 35 | "s3:ListMultipartUploadParts", 36 | ] 37 | resources = var.velero_s3_bucket_path_arns 38 | } 39 | 40 | statement { 41 | sid = "S3List" 42 | actions = [ 43 | "s3:ListBucket", 44 | ] 45 | resources = coalescelist(var.velero_s3_bucket_arns, ["arn:${local.partition}:s3:::*"]) 46 | } 47 | 48 | dynamic "statement" { 49 | for_each = length(var.velero_kms_arns) > 0 ? [1] : [] 50 | 51 | content { 52 | actions = [ 53 | "kms:Encrypt", 54 | "kms:Decrypt", 55 | "kms:ReEncrypt*", 56 | "kms:GenerateDataKey*", 57 | "kms:DescribeKey", 58 | ] 59 | 60 | resources = var.velero_kms_arns 61 | } 62 | } 63 | } 64 | 65 | locals { 66 | velero_policy_name = coalesce(var.velero_policy_name, "${var.policy_name_prefix}Velero") 67 | } 68 | 69 | resource "aws_iam_policy" "velero" { 70 | count = var.create && var.attach_velero_policy ? 1 : 0 71 | 72 | name = var.use_name_prefix ? null : local.velero_policy_name 73 | name_prefix = var.use_name_prefix ? "${local.velero_policy_name}-" : null 74 | path = var.path 75 | description = "Permissions for Velero" 76 | policy = data.aws_iam_policy_document.velero[0].json 77 | 78 | tags = var.tags 79 | } 80 | 81 | resource "aws_iam_role_policy_attachment" "velero" { 82 | count = var.create && var.attach_velero_policy ? 1 : 0 83 | 84 | role = aws_iam_role.this[0].name 85 | policy_arn = aws_iam_policy.velero[0].arn 86 | } 87 | -------------------------------------------------------------------------------- /aws_efs_csi.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # EFS CSI Driver Policy 3 | ################################################################################ 4 | 5 | # https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/docs/iam-policy-example.json 6 | 7 | data "aws_iam_policy_document" "efs_csi" { 8 | count = var.create && var.attach_aws_efs_csi_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = [ 15 | "ec2:DescribeAvailabilityZones", 16 | "elasticfilesystem:DescribeAccessPoints", 17 | "elasticfilesystem:DescribeFileSystems", 18 | "elasticfilesystem:DescribeMountTargets", 19 | ] 20 | 21 | resources = ["*"] 22 | } 23 | 24 | statement { 25 | actions = ["elasticfilesystem:CreateAccessPoint"] 26 | resources = ["*"] 27 | 28 | condition { 29 | test = "StringLike" 30 | variable = "aws:RequestTag/efs.csi.aws.com/cluster" 31 | values = ["true"] 32 | } 33 | } 34 | 35 | statement { 36 | actions = ["elasticfilesystem:TagResource"] 37 | resources = ["*"] 38 | 39 | condition { 40 | test = "StringLike" 41 | variable = "aws:ResourceTag/efs.csi.aws.com/cluster" 42 | values = ["true"] 43 | } 44 | } 45 | 46 | statement { 47 | actions = ["elasticfilesystem:DeleteAccessPoint"] 48 | resources = ["*"] 49 | 50 | condition { 51 | test = "StringEquals" 52 | variable = "aws:ResourceTag/efs.csi.aws.com/cluster" 53 | values = ["true"] 54 | } 55 | } 56 | } 57 | 58 | locals { 59 | aws_efs_csi_policy_name = coalesce(var.aws_efs_csi_policy_name, "${var.policy_name_prefix}EFS_CSI") 60 | } 61 | 62 | resource "aws_iam_policy" "efs_csi" { 63 | count = var.create && var.attach_aws_efs_csi_policy ? 1 : 0 64 | 65 | name = var.use_name_prefix ? null : local.aws_efs_csi_policy_name 66 | name_prefix = var.use_name_prefix ? "${local.aws_efs_csi_policy_name}-" : null 67 | path = var.path 68 | description = "Permissions to manage EFS volumes via the container storage interface (CSI) driver" 69 | policy = data.aws_iam_policy_document.efs_csi[0].json 70 | 71 | tags = var.tags 72 | } 73 | 74 | resource "aws_iam_role_policy_attachment" "efs_csi" { 75 | count = var.create && var.attach_aws_efs_csi_policy ? 1 : 0 76 | 77 | role = aws_iam_role.this[0].name 78 | policy_arn = aws_iam_policy.efs_csi[0].arn 79 | } 80 | -------------------------------------------------------------------------------- /cluster_autoscaler.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Cluster Autoscaler Policy 3 | ################################################################################ 4 | 5 | # https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md 6 | 7 | data "aws_iam_policy_document" "cluster_autoscaler" { 8 | count = var.create && var.attach_cluster_autoscaler_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = [ 15 | "autoscaling:DescribeAutoScalingGroups", 16 | "autoscaling:DescribeAutoScalingInstances", 17 | "autoscaling:DescribeLaunchConfigurations", 18 | "autoscaling:DescribeScalingActivities", 19 | "autoscaling:DescribeTags", 20 | "ec2:DescribeLaunchTemplateVersions", 21 | "ec2:DescribeInstanceTypes", 22 | "eks:DescribeNodegroup", 23 | "ec2:DescribeImages", 24 | "ec2:GetInstanceTypesFromInstanceRequirements" 25 | ] 26 | 27 | resources = ["*"] 28 | } 29 | 30 | dynamic "statement" { 31 | for_each = toset(var.cluster_autoscaler_cluster_names) 32 | 33 | content { 34 | actions = [ 35 | "autoscaling:SetDesiredCapacity", 36 | "autoscaling:TerminateInstanceInAutoScalingGroup" 37 | ] 38 | 39 | resources = ["*"] 40 | 41 | condition { 42 | test = "StringEquals" 43 | variable = "autoscaling:ResourceTag/kubernetes.io/cluster/${statement.value}" 44 | values = ["owned"] 45 | } 46 | } 47 | } 48 | } 49 | 50 | locals { 51 | cluster_autoscaler_policy_name = coalesce(var.cluster_autoscaler_policy_name, "${var.policy_name_prefix}ClusterAutoscaler") 52 | } 53 | 54 | resource "aws_iam_policy" "cluster_autoscaler" { 55 | count = var.create && var.attach_cluster_autoscaler_policy ? 1 : 0 56 | 57 | name = var.use_name_prefix ? null : local.cluster_autoscaler_policy_name 58 | name_prefix = var.use_name_prefix ? "${local.cluster_autoscaler_policy_name}-" : null 59 | path = var.path 60 | description = "Permissions for Cluster Autoscaler" 61 | policy = data.aws_iam_policy_document.cluster_autoscaler[0].json 62 | 63 | tags = var.tags 64 | } 65 | 66 | resource "aws_iam_role_policy_attachment" "cluster_autoscaler" { 67 | count = var.create && var.attach_cluster_autoscaler_policy ? 1 : 0 68 | 69 | role = aws_iam_role.this[0].name 70 | policy_arn = aws_iam_policy.cluster_autoscaler[0].arn 71 | } 72 | -------------------------------------------------------------------------------- /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/eks-pod-identity/aws//wrappers" 16 | # Alternative source: 17 | # source = "git::git@github.com:terraform-aws-modules/terraform-aws-eks-pod-identity.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/eks-pod-identity/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 | -------------------------------------------------------------------------------- /aws_gateway_controller.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # AWS Gateway Controller Policy 3 | ################################################################################ 4 | 5 | # https://github.com/aws/aws-application-networking-k8s/blob/main/files/controller-installation/recommended-inline-policy.json 6 | 7 | data "aws_iam_policy_document" "aws_gateway_controller" { 8 | count = var.create && var.attach_aws_gateway_controller_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = [ 15 | "vpc-lattice:*", 16 | "ec2:DescribeVpcs", 17 | "ec2:DescribeSubnets", 18 | "ec2:DescribeTags", 19 | "ec2:DescribeSecurityGroups", 20 | "logs:CreateLogDelivery", 21 | "logs:GetLogDelivery", 22 | "logs:DescribeLogGroups", 23 | "logs:PutResourcePolicy", 24 | "logs:DescribeResourcePolicies", 25 | "logs:UpdateLogDelivery", 26 | "logs:DeleteLogDelivery", 27 | "logs:ListLogDeliveries", 28 | "tag:GetResources", 29 | "firehose:TagDeliveryStream", 30 | "s3:GetBucketPolicy", 31 | "s3:PutBucketPolicy", 32 | ] 33 | resources = ["*"] 34 | } 35 | 36 | statement { 37 | actions = ["iam:CreateServiceLinkedRole"] 38 | resources = ["arn:${local.partition}:iam::*:role/aws-service-role/vpc-lattice.amazonaws.com/AWSServiceRoleForVpcLattice"] 39 | 40 | condition { 41 | test = "StringLike" 42 | variable = "iam:AWSServiceName" 43 | values = ["vpc-lattice.amazonaws.com"] 44 | } 45 | } 46 | 47 | statement { 48 | actions = ["iam:CreateServiceLinkedRole"] 49 | resources = ["arn:${local.partition}:iam::*:role/aws-service-role/delivery.logs.amazonaws.com/AWSServiceRoleForLogDelivery"] 50 | 51 | condition { 52 | test = "StringLike" 53 | variable = "iam:AWSServiceName" 54 | values = ["delivery.logs.amazonaws.com"] 55 | } 56 | } 57 | } 58 | 59 | locals { 60 | aws_gateway_controller_policy_name = coalesce(var.aws_gateway_controller_policy_name, "${var.policy_name_prefix}GatewayController") 61 | } 62 | 63 | resource "aws_iam_policy" "aws_gateway_controller" { 64 | count = var.create && var.attach_aws_gateway_controller_policy ? 1 : 0 65 | 66 | name = var.use_name_prefix ? null : local.aws_gateway_controller_policy_name 67 | name_prefix = var.use_name_prefix ? "${local.aws_gateway_controller_policy_name}-" : null 68 | path = var.path 69 | description = "Permissions for the AWS Gateway Controller" 70 | policy = data.aws_iam_policy_document.aws_gateway_controller[0].json 71 | 72 | tags = var.tags 73 | } 74 | 75 | resource "aws_iam_role_policy_attachment" "aws_gateway_controller" { 76 | count = var.create && var.attach_aws_gateway_controller_policy ? 1 : 0 77 | 78 | role = aws_iam_role.this[0].name 79 | policy_arn = aws_iam_policy.aws_gateway_controller[0].arn 80 | } 81 | -------------------------------------------------------------------------------- /aws_vpc_cni.tf: -------------------------------------------------------------------------------- 1 | 2 | ################################################################################ 3 | # VPC CNI Policy 4 | ################################################################################ 5 | 6 | data "aws_iam_policy_document" "vpc_cni" { 7 | count = var.create && var.attach_aws_vpc_cni_policy ? 1 : 0 8 | 9 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 10 | override_policy_documents = var.override_policy_documents 11 | 12 | # https://docs.aws.amazon.com/eks/latest/userguide/cni-network-policy.html#cni-network-policy-setup 13 | dynamic "statement" { 14 | for_each = var.aws_vpc_cni_enable_cloudwatch_logs ? [1] : [] 15 | content { 16 | sid = "CloudWatchLogs" 17 | actions = [ 18 | "logs:DescribeLogGroups", 19 | "logs:CreateLogGroup", 20 | "logs:CreateLogStream", 21 | "logs:PutLogEvents", 22 | ] 23 | resources = ["*"] 24 | } 25 | } 26 | 27 | statement { 28 | actions = ["ec2:CreateTags"] 29 | resources = ["arn:${local.partition}:ec2:*:*:network-interface/*"] 30 | } 31 | 32 | # https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/iam-policy.md#sample-scope-down-iam-policy-for-ipv4-mode 33 | dynamic "statement" { 34 | for_each = var.aws_vpc_cni_enable_ipv4 ? [1] : [] 35 | 36 | content { 37 | actions = [ 38 | "ec2:AssignPrivateIpAddresses", 39 | "ec2:AttachNetworkInterface", 40 | "ec2:CreateNetworkInterface", 41 | "ec2:DeleteNetworkInterface", 42 | "ec2:DescribeInstances", 43 | "ec2:DescribeTags", 44 | "ec2:DescribeNetworkInterfaces", 45 | "ec2:DescribeInstanceTypes", 46 | "ec2:DescribeSubnets", 47 | "ec2:DetachNetworkInterface", 48 | "ec2:ModifyNetworkInterfaceAttribute", 49 | "ec2:UnassignPrivateIpAddresses", 50 | ] 51 | resources = ["*"] 52 | } 53 | } 54 | 55 | # https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html#cni-iam-role-create-ipv6-policy 56 | dynamic "statement" { 57 | for_each = var.aws_vpc_cni_enable_ipv6 ? [1] : [] 58 | 59 | content { 60 | actions = [ 61 | "ec2:AssignIpv6Addresses", 62 | "ec2:DescribeInstances", 63 | "ec2:DescribeTags", 64 | "ec2:DescribeNetworkInterfaces", 65 | "ec2:DescribeInstanceTypes", 66 | ] 67 | resources = ["*"] 68 | } 69 | } 70 | } 71 | 72 | locals { 73 | aws_vpc_cni_policy_name = coalesce(var.aws_vpc_cni_policy_name, "${var.policy_name_prefix}VPC_CNI") 74 | } 75 | 76 | resource "aws_iam_policy" "vpc_cni" { 77 | count = var.create && var.attach_aws_vpc_cni_policy ? 1 : 0 78 | 79 | name = var.use_name_prefix ? null : local.aws_vpc_cni_policy_name 80 | name_prefix = var.use_name_prefix ? "${local.aws_vpc_cni_policy_name}-" : null 81 | path = var.path 82 | description = "Permissions for Amazon VPC CNI" 83 | policy = data.aws_iam_policy_document.vpc_cni[0].json 84 | 85 | tags = var.tags 86 | } 87 | 88 | resource "aws_iam_role_policy_attachment" "vpc_cni" { 89 | count = var.create && var.attach_aws_vpc_cni_policy ? 1 : 0 90 | 91 | role = aws_iam_role.this[0].name 92 | policy_arn = aws_iam_policy.vpc_cni[0].arn 93 | } 94 | -------------------------------------------------------------------------------- /external_secrets.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # External Secrets Policy 3 | ################################################################################ 4 | 5 | # https://github.com/external-secrets/kubernetes-external-secrets#add-a-secret 6 | 7 | data "aws_iam_policy_document" "external_secrets" { 8 | count = var.create && var.attach_external_secrets_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | dynamic "statement" { 14 | for_each = length(var.external_secrets_ssm_parameter_arns) > 0 ? [1] : [] 15 | 16 | content { 17 | actions = ["ssm:DescribeParameters"] 18 | resources = ["*"] 19 | } 20 | } 21 | 22 | dynamic "statement" { 23 | for_each = length(var.external_secrets_ssm_parameter_arns) > 0 ? [1] : [] 24 | 25 | content { 26 | actions = [ 27 | "ssm:GetParameter", 28 | "ssm:GetParameters", 29 | "ssm:GetParametersByPath" 30 | ] 31 | 32 | resources = var.external_secrets_ssm_parameter_arns 33 | } 34 | } 35 | 36 | dynamic "statement" { 37 | for_each = length(var.external_secrets_secrets_manager_arns) > 0 ? [1] : [] 38 | 39 | content { 40 | actions = ["secretsmanager:ListSecrets", "secretsmanager:BatchGetSecretValue"] 41 | resources = ["*"] 42 | } 43 | } 44 | 45 | dynamic "statement" { 46 | for_each = length(var.external_secrets_secrets_manager_arns) > 0 ? [1] : [] 47 | 48 | content { 49 | actions = [ 50 | "secretsmanager:GetResourcePolicy", 51 | "secretsmanager:GetSecretValue", 52 | "secretsmanager:DescribeSecret", 53 | "secretsmanager:ListSecretVersionIds" 54 | ] 55 | 56 | resources = var.external_secrets_secrets_manager_arns 57 | } 58 | } 59 | 60 | statement { 61 | actions = ["kms:Decrypt"] 62 | resources = coalescelist(var.external_secrets_kms_key_arns, ["arn:${local.partition}:kms:*:*:key/*"]) 63 | } 64 | 65 | dynamic "statement" { 66 | for_each = length(var.external_secrets_secrets_manager_arns) > 0 && var.external_secrets_create_permission ? [1] : [] 67 | 68 | content { 69 | actions = [ 70 | "secretsmanager:CreateSecret", 71 | "secretsmanager:PutSecretValue", 72 | "secretsmanager:TagResource", 73 | ] 74 | 75 | resources = var.external_secrets_secrets_manager_arns 76 | } 77 | } 78 | 79 | dynamic "statement" { 80 | for_each = length(var.external_secrets_secrets_manager_arns) > 0 && var.external_secrets_create_permission ? [1] : [] 81 | 82 | content { 83 | actions = ["secretsmanager:DeleteSecret"] 84 | resources = var.external_secrets_secrets_manager_arns 85 | 86 | condition { 87 | test = "StringEquals" 88 | variable = "secretsmanager:ResourceTag/managed-by" 89 | values = ["external-secrets"] 90 | } 91 | } 92 | } 93 | } 94 | 95 | locals { 96 | external_secrets_policy_name = coalesce(var.external_secrets_policy_name, "${var.policy_name_prefix}ExternalSecrets") 97 | } 98 | 99 | resource "aws_iam_policy" "external_secrets" { 100 | count = var.create && var.attach_external_secrets_policy ? 1 : 0 101 | 102 | name = var.use_name_prefix ? null : local.external_secrets_policy_name 103 | name_prefix = var.use_name_prefix ? "${local.external_secrets_policy_name}-" : null 104 | path = var.path 105 | description = "Permissions for External Secrets" 106 | policy = data.aws_iam_policy_document.external_secrets[0].json 107 | 108 | tags = var.tags 109 | } 110 | 111 | resource "aws_iam_role_policy_attachment" "external_secrets" { 112 | count = var.create && var.attach_external_secrets_policy ? 1 : 0 113 | 114 | role = aws_iam_role.this[0].name 115 | policy_arn = aws_iam_policy.external_secrets[0].arn 116 | } 117 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # IAM Role 3 | ################################################################################ 4 | 5 | output "iam_role_arn" { 6 | description = "ARN of IAM role" 7 | value = try(aws_iam_role.this[0].arn, null) 8 | } 9 | 10 | output "iam_role_name" { 11 | description = "Name of IAM role" 12 | value = try(aws_iam_role.this[0].name, null) 13 | } 14 | 15 | output "iam_role_path" { 16 | description = "Path of IAM role" 17 | value = try(aws_iam_role.this[0].path, null) 18 | } 19 | 20 | output "iam_role_unique_id" { 21 | description = "Unique ID of IAM role" 22 | value = try(aws_iam_role.this[0].unique_id, null) 23 | } 24 | 25 | ################################################################################ 26 | # IAM Policy 27 | # Note: The module is designed to create a single IAM role with a single policy; 28 | # therefore, we only output one policy ARN, name, and ID (the first one that resolves) 29 | ################################################################################ 30 | 31 | output "iam_policy_arn" { 32 | description = "The ARN assigned by AWS to this policy" 33 | value = try( 34 | aws_iam_policy.amazon_managed_service_prometheus[0].arn, 35 | aws_iam_policy.appmesh_controller[0].arn, 36 | aws_iam_policy.appmesh_envoy_proxy[0].arn, 37 | aws_iam_policy.aws_gateway_controller[0].arn, 38 | aws_iam_policy.aws_privateca_issuer[0].arn, 39 | aws_iam_policy.cert_manager[0].arn, 40 | aws_iam_policy.cluster_autoscaler[0].arn, 41 | aws_iam_policy.ebs_csi[0].arn, 42 | aws_iam_policy.efs_csi[0].arn, 43 | aws_iam_policy.external_dns[0].arn, 44 | aws_iam_policy.external_secrets[0].arn, 45 | aws_iam_policy.fsx_lustre_csi[0].arn, 46 | aws_iam_policy.lb_controller[0].arn, 47 | aws_iam_policy.lb_controller_targetgroup_only[0].arn, 48 | aws_iam_policy.mountpoint_s3_csi[0].arn, 49 | aws_iam_policy.node_termination_handler[0].arn, 50 | aws_iam_policy.velero[0].arn, 51 | aws_iam_policy.vpc_cni[0].arn, 52 | aws_iam_policy.custom[0].arn, 53 | null, 54 | ) 55 | } 56 | 57 | output "iam_policy_name" { 58 | description = "Name of IAM policy" 59 | value = try( 60 | aws_iam_policy.amazon_managed_service_prometheus[0].name, 61 | aws_iam_policy.appmesh_controller[0].name, 62 | aws_iam_policy.appmesh_envoy_proxy[0].name, 63 | aws_iam_policy.aws_gateway_controller[0].name, 64 | aws_iam_policy.aws_privateca_issuer[0].name, 65 | aws_iam_policy.cert_manager[0].name, 66 | aws_iam_policy.cluster_autoscaler[0].name, 67 | aws_iam_policy.ebs_csi[0].name, 68 | aws_iam_policy.efs_csi[0].name, 69 | aws_iam_policy.external_dns[0].name, 70 | aws_iam_policy.external_secrets[0].name, 71 | aws_iam_policy.fsx_lustre_csi[0].name, 72 | aws_iam_policy.lb_controller[0].name, 73 | aws_iam_policy.lb_controller_targetgroup_only[0].name, 74 | aws_iam_policy.mountpoint_s3_csi[0].name, 75 | aws_iam_policy.node_termination_handler[0].name, 76 | aws_iam_policy.velero[0].name, 77 | aws_iam_policy.vpc_cni[0].name, 78 | aws_iam_policy.custom[0].name, 79 | null, 80 | ) 81 | } 82 | 83 | output "iam_policy_id" { 84 | description = "The policy's ID" 85 | value = try( 86 | aws_iam_policy.amazon_managed_service_prometheus[0].policy_id, 87 | aws_iam_policy.appmesh_controller[0].policy_id, 88 | aws_iam_policy.appmesh_envoy_proxy[0].policy_id, 89 | aws_iam_policy.aws_gateway_controller[0].policy_id, 90 | aws_iam_policy.aws_privateca_issuer[0].policy_id, 91 | aws_iam_policy.cert_manager[0].policy_id, 92 | aws_iam_policy.cluster_autoscaler[0].policy_id, 93 | aws_iam_policy.ebs_csi[0].policy_id, 94 | aws_iam_policy.efs_csi[0].policy_id, 95 | aws_iam_policy.external_dns[0].policy_id, 96 | aws_iam_policy.external_secrets[0].policy_id, 97 | aws_iam_policy.fsx_lustre_csi[0].policy_id, 98 | aws_iam_policy.lb_controller[0].policy_id, 99 | aws_iam_policy.lb_controller_targetgroup_only[0].policy_id, 100 | aws_iam_policy.mountpoint_s3_csi[0].policy_id, 101 | aws_iam_policy.node_termination_handler[0].policy_id, 102 | aws_iam_policy.velero[0].policy_id, 103 | aws_iam_policy.vpc_cni[0].policy_id, 104 | aws_iam_policy.custom[0].policy_id, 105 | null, 106 | ) 107 | } 108 | 109 | ################################################################################ 110 | # Pod Identity Association 111 | ################################################################################ 112 | 113 | output "associations" { 114 | description = "Map of Pod Identity associations created" 115 | value = aws_eks_pod_identity_association.this 116 | } 117 | -------------------------------------------------------------------------------- /aws_ebs_csi.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # EBS CSI Policy 3 | ################################################################################ 4 | 5 | # https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/example-iam-policy.json 6 | 7 | data "aws_iam_policy_document" "ebs_csi" { 8 | count = var.create && var.attach_aws_ebs_csi_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = [ 15 | "ec2:CreateSnapshot", 16 | "ec2:AttachVolume", 17 | "ec2:DetachVolume", 18 | "ec2:ModifyVolume", 19 | "ec2:DescribeAvailabilityZones", 20 | "ec2:DescribeInstances", 21 | "ec2:DescribeSnapshots", 22 | "ec2:DescribeTags", 23 | "ec2:DescribeVolumes", 24 | "ec2:DescribeVolumesModifications", 25 | "ec2:EnableFastSnapshotRestores", 26 | ] 27 | 28 | resources = ["*"] 29 | } 30 | 31 | statement { 32 | actions = ["ec2:CopyVolumes"] 33 | resources = ["arn:${local.partition}:ec2:*:*:volume/vol-*"] 34 | } 35 | 36 | statement { 37 | actions = ["ec2:CreateTags"] 38 | 39 | resources = [ 40 | "arn:${local.partition}:ec2:*:*:volume/*", 41 | "arn:${local.partition}:ec2:*:*:snapshot/*", 42 | ] 43 | 44 | condition { 45 | test = "StringEquals" 46 | variable = "ec2:CreateAction" 47 | values = [ 48 | "CreateVolume", 49 | "CreateSnapshot", 50 | "CopyVolumes", 51 | ] 52 | } 53 | } 54 | 55 | statement { 56 | actions = ["ec2:DeleteTags"] 57 | 58 | resources = [ 59 | "arn:${local.partition}:ec2:*:*:volume/*", 60 | "arn:${local.partition}:ec2:*:*:snapshot/*", 61 | ] 62 | } 63 | 64 | statement { 65 | actions = [ 66 | "ec2:CreateVolume", 67 | "ec2:CopyVolumes", 68 | ] 69 | resources = ["arn:${local.partition}:ec2:*:*:volume/*"] 70 | 71 | condition { 72 | test = "StringLike" 73 | variable = "aws:RequestTag/ebs.csi.aws.com/cluster" 74 | values = ["true"] 75 | } 76 | } 77 | 78 | statement { 79 | actions = [ 80 | "ec2:CreateVolume", 81 | "ec2:CopyVolumes", 82 | ] 83 | resources = ["arn:${local.partition}:ec2:*:*:volume/*"] 84 | 85 | condition { 86 | test = "StringLike" 87 | variable = "aws:RequestTag/CSIVolumeName" 88 | values = ["*"] 89 | } 90 | } 91 | 92 | statement { 93 | actions = ["ec2:CreateVolume"] 94 | resources = ["arn:${local.partition}:ec2:*:*:snapshot/*"] 95 | } 96 | 97 | statement { 98 | actions = ["ec2:DeleteVolume"] 99 | resources = ["*"] 100 | 101 | condition { 102 | test = "StringLike" 103 | variable = "ec2:ResourceTag/ebs.csi.aws.com/cluster" 104 | values = ["true"] 105 | } 106 | } 107 | 108 | statement { 109 | actions = ["ec2:DeleteVolume"] 110 | resources = ["*"] 111 | 112 | condition { 113 | test = "StringLike" 114 | variable = "ec2:ResourceTag/CSIVolumeName" 115 | values = ["*"] 116 | } 117 | } 118 | 119 | statement { 120 | actions = ["ec2:DeleteVolume"] 121 | resources = ["*"] 122 | 123 | condition { 124 | test = "StringLike" 125 | variable = "ec2:ResourceTag/kubernetes.io/created-for/pvc/name" 126 | values = ["*"] 127 | } 128 | } 129 | 130 | statement { 131 | actions = ["ec2:DeleteSnapshot"] 132 | resources = ["*"] 133 | 134 | condition { 135 | test = "StringLike" 136 | variable = "ec2:ResourceTag/CSIVolumeSnapshotName" 137 | values = ["*"] 138 | } 139 | } 140 | 141 | statement { 142 | actions = ["ec2:DeleteSnapshot"] 143 | resources = ["*"] 144 | 145 | condition { 146 | test = "StringLike" 147 | variable = "ec2:ResourceTag/ebs.csi.aws.com/cluster" 148 | values = ["true"] 149 | } 150 | } 151 | 152 | dynamic "statement" { 153 | for_each = length(var.aws_ebs_csi_kms_arns) > 0 ? [1] : [] 154 | 155 | content { 156 | actions = [ 157 | "kms:CreateGrant", 158 | "kms:ListGrants", 159 | "kms:RevokeGrant", 160 | ] 161 | 162 | resources = var.aws_ebs_csi_kms_arns 163 | 164 | condition { 165 | test = "Bool" 166 | variable = "kms:GrantIsForAWSResource" 167 | values = [true] 168 | } 169 | } 170 | } 171 | 172 | dynamic "statement" { 173 | for_each = length(var.aws_ebs_csi_kms_arns) > 0 ? [1] : [] 174 | 175 | content { 176 | actions = [ 177 | "kms:Encrypt", 178 | "kms:Decrypt", 179 | "kms:ReEncrypt*", 180 | "kms:GenerateDataKey*", 181 | "kms:DescribeKey", 182 | ] 183 | 184 | resources = var.aws_ebs_csi_kms_arns 185 | } 186 | } 187 | } 188 | 189 | locals { 190 | aws_ebs_csi_policy_name = coalesce(var.aws_ebs_csi_policy_name, "${var.policy_name_prefix}EBS_CSI") 191 | } 192 | 193 | resource "aws_iam_policy" "ebs_csi" { 194 | count = var.create && var.attach_aws_ebs_csi_policy ? 1 : 0 195 | 196 | name = var.use_name_prefix ? null : local.aws_ebs_csi_policy_name 197 | name_prefix = var.use_name_prefix ? "${local.aws_ebs_csi_policy_name}-" : null 198 | path = var.path 199 | description = "Permissions to manage EBS volumes via the container storage interface (CSI) driver" 200 | policy = data.aws_iam_policy_document.ebs_csi[0].json 201 | 202 | tags = var.tags 203 | } 204 | 205 | resource "aws_iam_role_policy_attachment" "ebs_csi" { 206 | count = var.create && var.attach_aws_ebs_csi_policy ? 1 : 0 207 | 208 | role = aws_iam_role.this[0].name 209 | policy_arn = aws_iam_policy.ebs_csi[0].arn 210 | } 211 | -------------------------------------------------------------------------------- /aws_appmesh.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # AWS AppMesh Controller 3 | ################################################################################ 4 | 5 | # https://github.com/aws/eks-charts/tree/master/stable/appmesh-controller#prerequisites 6 | # https://raw.githubusercontent.com/aws/aws-app-mesh-controller-for-k8s/master/config/iam/controller-iam-policy.json 7 | 8 | data "aws_iam_policy_document" "appmesh_controller" { 9 | count = var.create && var.attach_aws_appmesh_controller_policy ? 1 : 0 10 | 11 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 12 | override_policy_documents = var.override_policy_documents 13 | 14 | statement { 15 | actions = [ 16 | "appmesh:ListVirtualRouters", 17 | "appmesh:ListVirtualServices", 18 | "appmesh:ListRoutes", 19 | "appmesh:ListGatewayRoutes", 20 | "appmesh:ListMeshes", 21 | "appmesh:ListVirtualNodes", 22 | "appmesh:ListVirtualGateways", 23 | "appmesh:DescribeMesh", 24 | "appmesh:DescribeVirtualRouter", 25 | "appmesh:DescribeRoute", 26 | "appmesh:DescribeVirtualNode", 27 | "appmesh:DescribeVirtualGateway", 28 | "appmesh:DescribeGatewayRoute", 29 | "appmesh:DescribeVirtualService", 30 | "appmesh:CreateMesh", 31 | "appmesh:CreateVirtualRouter", 32 | "appmesh:CreateVirtualGateway", 33 | "appmesh:CreateVirtualService", 34 | "appmesh:CreateGatewayRoute", 35 | "appmesh:CreateRoute", 36 | "appmesh:CreateVirtualNode", 37 | "appmesh:UpdateMesh", 38 | "appmesh:UpdateRoute", 39 | "appmesh:UpdateVirtualGateway", 40 | "appmesh:UpdateVirtualRouter", 41 | "appmesh:UpdateGatewayRoute", 42 | "appmesh:UpdateVirtualService", 43 | "appmesh:UpdateVirtualNode", 44 | "appmesh:DeleteMesh", 45 | "appmesh:DeleteRoute", 46 | "appmesh:DeleteVirtualRouter", 47 | "appmesh:DeleteGatewayRoute", 48 | "appmesh:DeleteVirtualService", 49 | "appmesh:DeleteVirtualNode", 50 | "appmesh:DeleteVirtualGateway" 51 | ] 52 | resources = ["*"] 53 | } 54 | 55 | statement { 56 | actions = [ 57 | "iam:CreateServiceLinkedRole" 58 | ] 59 | resources = ["arn:${local.partition}:iam::*:role/aws-service-role/appmesh.amazonaws.com/AWSServiceRoleForAppMesh"] 60 | condition { 61 | test = "StringLike" 62 | variable = "iam:AWSServiceName" 63 | values = ["appmesh.amazonaws.com"] 64 | } 65 | } 66 | 67 | statement { 68 | actions = [ 69 | "acm:ListCertificates", 70 | "acm:DescribeCertificate", 71 | "acm-pca:DescribeCertificateAuthority", 72 | "acm-pca:ListCertificateAuthorities" 73 | ] 74 | resources = ["*"] 75 | } 76 | 77 | statement { 78 | actions = [ 79 | "servicediscovery:CreateService", 80 | "servicediscovery:DeleteService", 81 | "servicediscovery:GetService", 82 | "servicediscovery:GetInstance", 83 | "servicediscovery:RegisterInstance", 84 | "servicediscovery:DeregisterInstance", 85 | "servicediscovery:ListInstances", 86 | "servicediscovery:ListNamespaces", 87 | "servicediscovery:ListServices", 88 | "servicediscovery:GetInstancesHealthStatus", 89 | "servicediscovery:UpdateInstanceCustomHealthStatus", 90 | "servicediscovery:GetOperation", 91 | "route53:GetHealthCheck", 92 | "route53:CreateHealthCheck", 93 | "route53:UpdateHealthCheck", 94 | "route53:ChangeResourceRecordSets", 95 | "route53:DeleteHealthCheck" 96 | ] 97 | resources = ["*"] 98 | } 99 | } 100 | 101 | locals { 102 | appmesh_controller_policy_name = coalesce(var.appmesh_controller_policy_name, "${var.policy_name_prefix}AppMeshController") 103 | } 104 | 105 | resource "aws_iam_policy" "appmesh_controller" { 106 | count = var.create && var.attach_aws_appmesh_controller_policy ? 1 : 0 107 | 108 | name = var.use_name_prefix ? null : local.appmesh_controller_policy_name 109 | name_prefix = var.use_name_prefix ? "${local.appmesh_controller_policy_name}-" : null 110 | path = var.path 111 | description = "Permissions for AppMesh Controller" 112 | policy = data.aws_iam_policy_document.appmesh_controller[0].json 113 | 114 | tags = var.tags 115 | } 116 | 117 | resource "aws_iam_role_policy_attachment" "appmesh_controller" { 118 | count = var.create && var.attach_aws_appmesh_controller_policy ? 1 : 0 119 | 120 | role = aws_iam_role.this[0].name 121 | policy_arn = aws_iam_policy.appmesh_controller[0].arn 122 | } 123 | 124 | ################################################################################ 125 | # AWS AppMesh Envoy Proxy 126 | ################################################################################ 127 | 128 | # https://github.com/aws/aws-app-mesh-controller-for-k8s/blob/f4a551399c4a4428d31692d0e6d944c2b78f2753/config/helm/appmesh-controller/README.md#with-irsa 129 | # https://raw.githubusercontent.com/aws/aws-app-mesh-controller-for-k8s/master/config/iam/envoy-iam-policy.json 130 | 131 | data "aws_iam_policy_document" "appmesh_envoy_proxy" { 132 | count = var.create && var.attach_aws_appmesh_envoy_proxy_policy ? 1 : 0 133 | 134 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 135 | override_policy_documents = var.override_policy_documents 136 | 137 | statement { 138 | actions = [ 139 | "appmesh:StreamAggregatedResources" 140 | ] 141 | resources = ["*"] 142 | } 143 | 144 | statement { 145 | actions = [ 146 | "acm:ExportCertificate", 147 | "acm-pca:GetCertificateAuthorityCertificate" 148 | ] 149 | resources = ["*"] 150 | } 151 | } 152 | 153 | locals { 154 | appmesh_envoy_proxy_policy_name = coalesce(var.appmesh_envoy_proxy_policy_name, "${var.policy_name_prefix}AppMeshEnvoyProxy") 155 | } 156 | 157 | resource "aws_iam_policy" "appmesh_envoy_proxy" { 158 | count = var.create && var.attach_aws_appmesh_envoy_proxy_policy ? 1 : 0 159 | 160 | name = var.use_name_prefix ? null : local.appmesh_envoy_proxy_policy_name 161 | name_prefix = var.use_name_prefix ? "${local.appmesh_envoy_proxy_policy_name}-" : null 162 | path = var.path 163 | description = "Permissions for AppMesh Envoy Proxy" 164 | policy = data.aws_iam_policy_document.appmesh_envoy_proxy[0].json 165 | 166 | tags = var.tags 167 | } 168 | 169 | resource "aws_iam_role_policy_attachment" "appmesh_envoy_proxy" { 170 | count = var.create && var.attach_aws_appmesh_envoy_proxy_policy ? 1 : 0 171 | 172 | role = aws_iam_role.this[0].name 173 | policy_arn = aws_iam_policy.appmesh_envoy_proxy[0].arn 174 | } 175 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | data "aws_partition" "current" { 2 | count = var.create ? 1 : 0 3 | } 4 | 5 | data "aws_caller_identity" "current" { 6 | count = var.create ? 1 : 0 7 | } 8 | 9 | data "aws_region" "current" { 10 | count = var.create ? 1 : 0 11 | 12 | region = var.region 13 | } 14 | 15 | locals { 16 | partition = try(data.aws_partition.current[0].partition, "aws") 17 | account_id = try(data.aws_caller_identity.current[0].account_id, "") 18 | region = try(data.aws_region.current[0].region, "") 19 | } 20 | 21 | ################################################################################ 22 | # IAM Role Trust Policy 23 | ################################################################################ 24 | 25 | data "aws_iam_policy_document" "assume" { 26 | count = var.create ? 1 : 0 27 | 28 | statement { 29 | effect = "Allow" 30 | actions = [ 31 | "sts:AssumeRole", 32 | "sts:TagSession", 33 | ] 34 | 35 | principals { 36 | type = "Service" 37 | identifiers = ["pods.eks.amazonaws.com"] 38 | } 39 | 40 | dynamic "condition" { 41 | for_each = var.trust_policy_conditions 42 | 43 | content { 44 | test = condition.value.test 45 | values = condition.value.values 46 | variable = condition.value.variable 47 | } 48 | } 49 | } 50 | 51 | dynamic "statement" { 52 | for_each = var.trust_policy_statements != null ? var.trust_policy_statements : [] 53 | 54 | content { 55 | sid = statement.value.sid 56 | actions = statement.value.actions 57 | not_actions = statement.value.not_actions 58 | effect = statement.value.effect 59 | resources = statement.value.resources 60 | not_resources = statement.value.not_resources 61 | 62 | dynamic "principals" { 63 | for_each = statement.value.principals != null ? statement.value.principals : [] 64 | 65 | content { 66 | type = principals.value.type 67 | identifiers = principals.value.identifiers 68 | } 69 | } 70 | 71 | dynamic "not_principals" { 72 | for_each = statement.value.not_principals != null ? statement.value.not_principals : [] 73 | 74 | content { 75 | type = not_principals.value.type 76 | identifiers = not_principals.value.identifiers 77 | } 78 | } 79 | 80 | dynamic "condition" { 81 | for_each = statement.value.condition != null ? statement.value.condition : [] 82 | 83 | content { 84 | test = condition.value.test 85 | values = condition.value.values 86 | variable = condition.value.variable 87 | } 88 | } 89 | } 90 | } 91 | } 92 | 93 | ################################################################################ 94 | # IAM Role 95 | ################################################################################ 96 | 97 | resource "aws_iam_role" "this" { 98 | count = var.create ? 1 : 0 99 | 100 | name = var.use_name_prefix ? null : var.name 101 | name_prefix = var.use_name_prefix ? "${var.name}-" : null 102 | path = var.path 103 | description = var.description 104 | 105 | assume_role_policy = data.aws_iam_policy_document.assume[0].json 106 | max_session_duration = var.max_session_duration 107 | permissions_boundary = var.permissions_boundary_arn 108 | force_detach_policies = true 109 | 110 | tags = var.tags 111 | } 112 | 113 | resource "aws_iam_role_policy_attachment" "this" { 114 | for_each = { for k, v in var.additional_policy_arns : k => v if var.create } 115 | 116 | role = aws_iam_role.this[0].name 117 | policy_arn = each.value 118 | } 119 | 120 | ################################################################################ 121 | # Base IAM Policy Document 122 | ################################################################################ 123 | 124 | data "aws_iam_policy_document" "base" { 125 | count = var.create ? 1 : 0 126 | 127 | source_policy_documents = var.source_policy_documents 128 | # Override will happen on each final document 129 | # Here, it is only applicable for the custom policy document to avoid duplicate statements 130 | override_policy_documents = var.attach_custom_policy ? var.override_policy_documents : [] 131 | 132 | dynamic "statement" { 133 | for_each = var.policy_statements != null ? var.policy_statements : [] 134 | 135 | content { 136 | sid = statement.value.sid 137 | actions = statement.value.actions 138 | not_actions = statement.value.not_actions 139 | effect = statement.value.effect 140 | resources = statement.value.resources 141 | not_resources = statement.value.not_resources 142 | 143 | dynamic "principals" { 144 | for_each = statement.value.principals != null ? statement.value.principals : [] 145 | 146 | content { 147 | type = principals.value.type 148 | identifiers = principals.value.identifiers 149 | } 150 | } 151 | 152 | dynamic "not_principals" { 153 | for_each = statement.value.not_principals != null ? statement.value.not_principals : [] 154 | 155 | content { 156 | type = not_principals.value.type 157 | identifiers = not_principals.value.identifiers 158 | } 159 | } 160 | 161 | dynamic "condition" { 162 | for_each = statement.value.condition != null ? statement.value.condition : [] 163 | 164 | content { 165 | test = condition.value.test 166 | values = condition.value.values 167 | variable = condition.value.variable 168 | } 169 | } 170 | } 171 | } 172 | } 173 | 174 | ################################################################################ 175 | # Custom IAM Policy 176 | ################################################################################ 177 | 178 | resource "aws_iam_policy" "custom" { 179 | count = var.create && var.attach_custom_policy ? 1 : 0 180 | 181 | name = var.use_name_prefix ? null : var.name 182 | name_prefix = var.use_name_prefix ? "${var.name}-" : null 183 | path = var.path 184 | description = var.custom_policy_description 185 | policy = data.aws_iam_policy_document.base[0].json 186 | 187 | tags = var.tags 188 | } 189 | 190 | resource "aws_iam_role_policy_attachment" "custom" { 191 | count = var.create && var.attach_custom_policy ? 1 : 0 192 | 193 | role = aws_iam_role.this[0].name 194 | policy_arn = aws_iam_policy.custom[0].arn 195 | } 196 | 197 | ################################################################################ 198 | # Pod Identity Association 199 | ################################################################################ 200 | 201 | resource "aws_eks_pod_identity_association" "this" { 202 | for_each = { for k, v in var.associations : k => v if var.create } 203 | 204 | region = var.region 205 | 206 | cluster_name = try(coalesce(each.value.cluster_name, var.association_defaults.cluster_name)) 207 | disable_session_tags = try(coalesce(each.value.disable_session_tags, var.association_defaults.disable_session_tags), null) 208 | namespace = try(coalesce(each.value.namespace, var.association_defaults.namespace)) 209 | role_arn = aws_iam_role.this[0].arn 210 | service_account = try(coalesce(each.value.service_account, var.association_defaults.service_account)) 211 | target_role_arn = try(coalesce(each.value.target_role_arn, var.association_defaults.target_role_arn), null) 212 | 213 | tags = merge( 214 | var.tags, 215 | each.value.tags, 216 | var.association_defaults.tags, 217 | ) 218 | } 219 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /wrappers/main.tf: -------------------------------------------------------------------------------- 1 | module "wrapper" { 2 | source = "../" 3 | 4 | for_each = var.items 5 | 6 | additional_policy_arns = try(each.value.additional_policy_arns, var.defaults.additional_policy_arns, {}) 7 | amazon_managed_service_prometheus_policy_name = try(each.value.amazon_managed_service_prometheus_policy_name, var.defaults.amazon_managed_service_prometheus_policy_name, null) 8 | amazon_managed_service_prometheus_workspace_arns = try(each.value.amazon_managed_service_prometheus_workspace_arns, var.defaults.amazon_managed_service_prometheus_workspace_arns, []) 9 | appmesh_controller_policy_name = try(each.value.appmesh_controller_policy_name, var.defaults.appmesh_controller_policy_name, null) 10 | appmesh_envoy_proxy_policy_name = try(each.value.appmesh_envoy_proxy_policy_name, var.defaults.appmesh_envoy_proxy_policy_name, null) 11 | association_defaults = try(each.value.association_defaults, var.defaults.association_defaults, {}) 12 | associations = try(each.value.associations, var.defaults.associations, {}) 13 | attach_amazon_managed_service_prometheus_policy = try(each.value.attach_amazon_managed_service_prometheus_policy, var.defaults.attach_amazon_managed_service_prometheus_policy, false) 14 | attach_aws_appmesh_controller_policy = try(each.value.attach_aws_appmesh_controller_policy, var.defaults.attach_aws_appmesh_controller_policy, false) 15 | attach_aws_appmesh_envoy_proxy_policy = try(each.value.attach_aws_appmesh_envoy_proxy_policy, var.defaults.attach_aws_appmesh_envoy_proxy_policy, false) 16 | attach_aws_cloudwatch_observability_policy = try(each.value.attach_aws_cloudwatch_observability_policy, var.defaults.attach_aws_cloudwatch_observability_policy, false) 17 | attach_aws_ebs_csi_policy = try(each.value.attach_aws_ebs_csi_policy, var.defaults.attach_aws_ebs_csi_policy, false) 18 | attach_aws_efs_csi_policy = try(each.value.attach_aws_efs_csi_policy, var.defaults.attach_aws_efs_csi_policy, false) 19 | attach_aws_fsx_lustre_csi_policy = try(each.value.attach_aws_fsx_lustre_csi_policy, var.defaults.attach_aws_fsx_lustre_csi_policy, false) 20 | attach_aws_gateway_controller_policy = try(each.value.attach_aws_gateway_controller_policy, var.defaults.attach_aws_gateway_controller_policy, false) 21 | attach_aws_lb_controller_policy = try(each.value.attach_aws_lb_controller_policy, var.defaults.attach_aws_lb_controller_policy, false) 22 | attach_aws_lb_controller_targetgroup_binding_only_policy = try(each.value.attach_aws_lb_controller_targetgroup_binding_only_policy, var.defaults.attach_aws_lb_controller_targetgroup_binding_only_policy, false) 23 | attach_aws_node_termination_handler_policy = try(each.value.attach_aws_node_termination_handler_policy, var.defaults.attach_aws_node_termination_handler_policy, false) 24 | attach_aws_privateca_issuer_policy = try(each.value.attach_aws_privateca_issuer_policy, var.defaults.attach_aws_privateca_issuer_policy, false) 25 | attach_aws_vpc_cni_policy = try(each.value.attach_aws_vpc_cni_policy, var.defaults.attach_aws_vpc_cni_policy, false) 26 | attach_cert_manager_policy = try(each.value.attach_cert_manager_policy, var.defaults.attach_cert_manager_policy, false) 27 | attach_cluster_autoscaler_policy = try(each.value.attach_cluster_autoscaler_policy, var.defaults.attach_cluster_autoscaler_policy, false) 28 | attach_custom_policy = try(each.value.attach_custom_policy, var.defaults.attach_custom_policy, false) 29 | attach_external_dns_policy = try(each.value.attach_external_dns_policy, var.defaults.attach_external_dns_policy, false) 30 | attach_external_secrets_policy = try(each.value.attach_external_secrets_policy, var.defaults.attach_external_secrets_policy, false) 31 | attach_mountpoint_s3_csi_policy = try(each.value.attach_mountpoint_s3_csi_policy, var.defaults.attach_mountpoint_s3_csi_policy, false) 32 | attach_pganalyze_policy = try(each.value.attach_pganalyze_policy, var.defaults.attach_pganalyze_policy, false) 33 | attach_velero_policy = try(each.value.attach_velero_policy, var.defaults.attach_velero_policy, false) 34 | aws_ebs_csi_kms_arns = try(each.value.aws_ebs_csi_kms_arns, var.defaults.aws_ebs_csi_kms_arns, []) 35 | aws_ebs_csi_policy_name = try(each.value.aws_ebs_csi_policy_name, var.defaults.aws_ebs_csi_policy_name, null) 36 | aws_efs_csi_policy_name = try(each.value.aws_efs_csi_policy_name, var.defaults.aws_efs_csi_policy_name, null) 37 | aws_fsx_lustre_csi_policy_name = try(each.value.aws_fsx_lustre_csi_policy_name, var.defaults.aws_fsx_lustre_csi_policy_name, null) 38 | aws_fsx_lustre_csi_service_role_arns = try(each.value.aws_fsx_lustre_csi_service_role_arns, var.defaults.aws_fsx_lustre_csi_service_role_arns, []) 39 | aws_gateway_controller_policy_name = try(each.value.aws_gateway_controller_policy_name, var.defaults.aws_gateway_controller_policy_name, null) 40 | aws_lb_controller_policy_name = try(each.value.aws_lb_controller_policy_name, var.defaults.aws_lb_controller_policy_name, null) 41 | aws_lb_controller_targetgroup_arns = try(each.value.aws_lb_controller_targetgroup_arns, var.defaults.aws_lb_controller_targetgroup_arns, []) 42 | aws_lb_controller_targetgroup_only_policy_name = try(each.value.aws_lb_controller_targetgroup_only_policy_name, var.defaults.aws_lb_controller_targetgroup_only_policy_name, null) 43 | aws_node_termination_handler_policy_name = try(each.value.aws_node_termination_handler_policy_name, var.defaults.aws_node_termination_handler_policy_name, null) 44 | aws_node_termination_handler_sqs_queue_arns = try(each.value.aws_node_termination_handler_sqs_queue_arns, var.defaults.aws_node_termination_handler_sqs_queue_arns, []) 45 | aws_privateca_issuer_acmca_arns = try(each.value.aws_privateca_issuer_acmca_arns, var.defaults.aws_privateca_issuer_acmca_arns, []) 46 | aws_privateca_issuer_policy_name = try(each.value.aws_privateca_issuer_policy_name, var.defaults.aws_privateca_issuer_policy_name, null) 47 | aws_vpc_cni_enable_cloudwatch_logs = try(each.value.aws_vpc_cni_enable_cloudwatch_logs, var.defaults.aws_vpc_cni_enable_cloudwatch_logs, false) 48 | aws_vpc_cni_enable_ipv4 = try(each.value.aws_vpc_cni_enable_ipv4, var.defaults.aws_vpc_cni_enable_ipv4, false) 49 | aws_vpc_cni_enable_ipv6 = try(each.value.aws_vpc_cni_enable_ipv6, var.defaults.aws_vpc_cni_enable_ipv6, false) 50 | aws_vpc_cni_policy_name = try(each.value.aws_vpc_cni_policy_name, var.defaults.aws_vpc_cni_policy_name, null) 51 | cert_manager_hosted_zone_arns = try(each.value.cert_manager_hosted_zone_arns, var.defaults.cert_manager_hosted_zone_arns, []) 52 | cert_manager_policy_name = try(each.value.cert_manager_policy_name, var.defaults.cert_manager_policy_name, null) 53 | cluster_autoscaler_cluster_names = try(each.value.cluster_autoscaler_cluster_names, var.defaults.cluster_autoscaler_cluster_names, []) 54 | cluster_autoscaler_policy_name = try(each.value.cluster_autoscaler_policy_name, var.defaults.cluster_autoscaler_policy_name, null) 55 | create = try(each.value.create, var.defaults.create, true) 56 | custom_policy_description = try(each.value.custom_policy_description, var.defaults.custom_policy_description, "Custom IAM Policy") 57 | description = try(each.value.description, var.defaults.description, null) 58 | external_dns_hosted_zone_arns = try(each.value.external_dns_hosted_zone_arns, var.defaults.external_dns_hosted_zone_arns, []) 59 | external_dns_policy_name = try(each.value.external_dns_policy_name, var.defaults.external_dns_policy_name, null) 60 | external_secrets_create_permission = try(each.value.external_secrets_create_permission, var.defaults.external_secrets_create_permission, false) 61 | external_secrets_kms_key_arns = try(each.value.external_secrets_kms_key_arns, var.defaults.external_secrets_kms_key_arns, []) 62 | external_secrets_policy_name = try(each.value.external_secrets_policy_name, var.defaults.external_secrets_policy_name, null) 63 | external_secrets_secrets_manager_arns = try(each.value.external_secrets_secrets_manager_arns, var.defaults.external_secrets_secrets_manager_arns, []) 64 | external_secrets_ssm_parameter_arns = try(each.value.external_secrets_ssm_parameter_arns, var.defaults.external_secrets_ssm_parameter_arns, []) 65 | max_session_duration = try(each.value.max_session_duration, var.defaults.max_session_duration, null) 66 | mountpoint_s3_csi_bucket_arns = try(each.value.mountpoint_s3_csi_bucket_arns, var.defaults.mountpoint_s3_csi_bucket_arns, []) 67 | mountpoint_s3_csi_bucket_path_arns = try(each.value.mountpoint_s3_csi_bucket_path_arns, var.defaults.mountpoint_s3_csi_bucket_path_arns, []) 68 | mountpoint_s3_csi_policy_name = try(each.value.mountpoint_s3_csi_policy_name, var.defaults.mountpoint_s3_csi_policy_name, null) 69 | name = try(each.value.name, var.defaults.name, "") 70 | override_policy_documents = try(each.value.override_policy_documents, var.defaults.override_policy_documents, []) 71 | path = try(each.value.path, var.defaults.path, "/") 72 | permissions_boundary_arn = try(each.value.permissions_boundary_arn, var.defaults.permissions_boundary_arn, null) 73 | pganalyze_policy_name = try(each.value.pganalyze_policy_name, var.defaults.pganalyze_policy_name, null) 74 | policy_name_prefix = try(each.value.policy_name_prefix, var.defaults.policy_name_prefix, "AmazonEKS_") 75 | policy_statements = try(each.value.policy_statements, var.defaults.policy_statements, null) 76 | region = try(each.value.region, var.defaults.region, null) 77 | source_policy_documents = try(each.value.source_policy_documents, var.defaults.source_policy_documents, []) 78 | tags = try(each.value.tags, var.defaults.tags, {}) 79 | trust_policy_conditions = try(each.value.trust_policy_conditions, var.defaults.trust_policy_conditions, []) 80 | trust_policy_statements = try(each.value.trust_policy_statements, var.defaults.trust_policy_statements, null) 81 | use_name_prefix = try(each.value.use_name_prefix, var.defaults.use_name_prefix, true) 82 | velero_kms_arns = try(each.value.velero_kms_arns, var.defaults.velero_kms_arns, []) 83 | velero_policy_name = try(each.value.velero_policy_name, var.defaults.velero_policy_name, null) 84 | velero_s3_bucket_arns = try(each.value.velero_s3_bucket_arns, var.defaults.velero_s3_bucket_arns, []) 85 | velero_s3_bucket_path_arns = try(each.value.velero_s3_bucket_path_arns, var.defaults.velero_s3_bucket_path_arns, []) 86 | } 87 | -------------------------------------------------------------------------------- /aws_lb_controller.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # AWS Load Balancer Controller Policy 3 | ################################################################################ 4 | 5 | # https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/install/iam_policy.json 6 | 7 | data "aws_iam_policy_document" "lb_controller" { 8 | count = var.create && var.attach_aws_lb_controller_policy ? 1 : 0 9 | 10 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 11 | override_policy_documents = var.override_policy_documents 12 | 13 | statement { 14 | actions = ["iam:CreateServiceLinkedRole"] 15 | resources = ["*"] 16 | 17 | condition { 18 | test = "StringEquals" 19 | variable = "iam:AWSServiceName" 20 | values = ["elasticloadbalancing.amazonaws.com"] 21 | } 22 | } 23 | 24 | statement { 25 | actions = [ 26 | "ec2:DescribeAccountAttributes", 27 | "ec2:DescribeAddresses", 28 | "ec2:DescribeAvailabilityZones", 29 | "ec2:DescribeInternetGateways", 30 | "ec2:DescribeVpcs", 31 | "ec2:DescribeVpcPeeringConnections", 32 | "ec2:DescribeSubnets", 33 | "ec2:DescribeSecurityGroups", 34 | "ec2:DescribeInstances", 35 | "ec2:DescribeNetworkInterfaces", 36 | "ec2:DescribeTags", 37 | "ec2:GetCoipPoolUsage", 38 | "ec2:DescribeCoipPools", 39 | "ec2:GetSecurityGroupsForVpc", 40 | "ec2:DescribeIpamPools", 41 | "ec2:DescribeRouteTables", 42 | "elasticloadbalancing:DescribeLoadBalancers", 43 | "elasticloadbalancing:DescribeLoadBalancerAttributes", 44 | "elasticloadbalancing:DescribeListeners", 45 | "elasticloadbalancing:DescribeListenerCertificates", 46 | "elasticloadbalancing:DescribeSSLPolicies", 47 | "elasticloadbalancing:DescribeRules", 48 | "elasticloadbalancing:DescribeTargetGroups", 49 | "elasticloadbalancing:DescribeTargetGroupAttributes", 50 | "elasticloadbalancing:DescribeTargetHealth", 51 | "elasticloadbalancing:DescribeTags", 52 | "elasticloadbalancing:DescribeTrustStores", 53 | "elasticloadbalancing:DescribeListenerAttributes", 54 | "elasticloadbalancing:DescribeCapacityReservation", 55 | ] 56 | resources = ["*"] 57 | } 58 | 59 | statement { 60 | actions = [ 61 | "cognito-idp:DescribeUserPoolClient", 62 | "acm:ListCertificates", 63 | "acm:DescribeCertificate", 64 | "iam:ListServerCertificates", 65 | "iam:GetServerCertificate", 66 | "waf-regional:GetWebACL", 67 | "waf-regional:GetWebACLForResource", 68 | "waf-regional:AssociateWebACL", 69 | "waf-regional:DisassociateWebACL", 70 | "wafv2:GetWebACL", 71 | "wafv2:GetWebACLForResource", 72 | "wafv2:AssociateWebACL", 73 | "wafv2:DisassociateWebACL", 74 | "wafv2:ListWebACLs", 75 | "shield:GetSubscriptionState", 76 | "shield:DescribeProtection", 77 | "shield:CreateProtection", 78 | "shield:DeleteProtection", 79 | ] 80 | resources = ["*"] 81 | } 82 | 83 | statement { 84 | actions = [ 85 | "ec2:AuthorizeSecurityGroupIngress", 86 | "ec2:RevokeSecurityGroupIngress", 87 | ] 88 | resources = ["*"] 89 | } 90 | 91 | statement { 92 | actions = [ 93 | "ec2:CreateSecurityGroup", 94 | ] 95 | resources = ["*"] 96 | } 97 | 98 | statement { 99 | actions = ["ec2:CreateTags"] 100 | resources = ["arn:${local.partition}:ec2:*:*:security-group/*"] 101 | 102 | condition { 103 | test = "StringEquals" 104 | variable = "ec2:CreateAction" 105 | values = ["CreateSecurityGroup"] 106 | } 107 | 108 | condition { 109 | test = "Null" 110 | variable = "aws:RequestTag/elbv2.k8s.aws/cluster" 111 | values = ["false"] 112 | } 113 | } 114 | 115 | statement { 116 | actions = [ 117 | "ec2:CreateTags", 118 | "ec2:DeleteTags", 119 | ] 120 | resources = ["arn:${local.partition}:ec2:*:*:security-group/*"] 121 | 122 | condition { 123 | test = "Null" 124 | variable = "aws:RequestTag/elbv2.k8s.aws/cluster" 125 | values = ["true"] 126 | } 127 | 128 | condition { 129 | test = "Null" 130 | variable = "aws:ResourceTag/elbv2.k8s.aws/cluster" 131 | values = ["false"] 132 | } 133 | } 134 | 135 | statement { 136 | actions = [ 137 | "ec2:AuthorizeSecurityGroupIngress", 138 | "ec2:RevokeSecurityGroupIngress", 139 | "ec2:DeleteSecurityGroup", 140 | ] 141 | resources = ["*"] 142 | 143 | condition { 144 | test = "Null" 145 | variable = "aws:ResourceTag/elbv2.k8s.aws/cluster" 146 | values = ["false"] 147 | } 148 | } 149 | 150 | statement { 151 | actions = [ 152 | "elasticloadbalancing:CreateLoadBalancer", 153 | "elasticloadbalancing:CreateTargetGroup", 154 | ] 155 | resources = ["*"] 156 | 157 | condition { 158 | test = "Null" 159 | variable = "aws:RequestTag/elbv2.k8s.aws/cluster" 160 | values = ["false"] 161 | } 162 | } 163 | 164 | statement { 165 | actions = [ 166 | "elasticloadbalancing:CreateListener", 167 | "elasticloadbalancing:DeleteListener", 168 | "elasticloadbalancing:CreateRule", 169 | "elasticloadbalancing:DeleteRule", 170 | ] 171 | resources = ["*"] 172 | } 173 | 174 | statement { 175 | actions = [ 176 | "elasticloadbalancing:AddTags", 177 | "elasticloadbalancing:RemoveTags", 178 | ] 179 | resources = [ 180 | "arn:${local.partition}:elasticloadbalancing:*:*:targetgroup/*/*", 181 | "arn:${local.partition}:elasticloadbalancing:*:*:loadbalancer/net/*/*", 182 | "arn:${local.partition}:elasticloadbalancing:*:*:loadbalancer/app/*/*", 183 | ] 184 | 185 | condition { 186 | test = "Null" 187 | variable = "aws:RequestTag/elbv2.k8s.aws/cluster" 188 | values = ["true"] 189 | } 190 | 191 | condition { 192 | test = "Null" 193 | variable = "aws:ResourceTag/elbv2.k8s.aws/cluster" 194 | values = ["false"] 195 | } 196 | } 197 | 198 | statement { 199 | actions = [ 200 | "elasticloadbalancing:AddTags", 201 | "elasticloadbalancing:RemoveTags", 202 | ] 203 | resources = [ 204 | "arn:${local.partition}:elasticloadbalancing:*:*:listener/net/*/*/*", 205 | "arn:${local.partition}:elasticloadbalancing:*:*:listener/app/*/*/*", 206 | "arn:${local.partition}:elasticloadbalancing:*:*:listener-rule/net/*/*/*", 207 | "arn:${local.partition}:elasticloadbalancing:*:*:listener-rule/app/*/*/*", 208 | ] 209 | } 210 | 211 | statement { 212 | actions = [ 213 | "elasticloadbalancing:ModifyLoadBalancerAttributes", 214 | "elasticloadbalancing:SetIpAddressType", 215 | "elasticloadbalancing:SetSecurityGroups", 216 | "elasticloadbalancing:SetSubnets", 217 | "elasticloadbalancing:DeleteLoadBalancer", 218 | "elasticloadbalancing:ModifyTargetGroup", 219 | "elasticloadbalancing:ModifyTargetGroupAttributes", 220 | "elasticloadbalancing:DeleteTargetGroup", 221 | "elasticloadbalancing:ModifyListenerAttributes", 222 | "elasticloadbalancing:ModifyCapacityReservation", 223 | "elasticloadbalancing:ModifyIpPools" 224 | ] 225 | resources = ["*"] 226 | 227 | condition { 228 | test = "Null" 229 | variable = "aws:ResourceTag/elbv2.k8s.aws/cluster" 230 | values = ["false"] 231 | } 232 | } 233 | 234 | statement { 235 | actions = [ 236 | "elasticloadbalancing:AddTags" 237 | ] 238 | resources = [ 239 | "arn:${local.partition}:elasticloadbalancing:*:*:targetgroup/*/*", 240 | "arn:${local.partition}:elasticloadbalancing:*:*:loadbalancer/net/*/*", 241 | "arn:${local.partition}:elasticloadbalancing:*:*:loadbalancer/app/*/*", 242 | ] 243 | 244 | condition { 245 | test = "StringEquals" 246 | variable = "elasticloadbalancing:CreateAction" 247 | values = [ 248 | "CreateTargetGroup", 249 | "CreateLoadBalancer", 250 | ] 251 | } 252 | 253 | condition { 254 | test = "Null" 255 | variable = "aws:RequestTag/elbv2.k8s.aws/cluster" 256 | values = ["false"] 257 | } 258 | } 259 | 260 | statement { 261 | actions = [ 262 | "elasticloadbalancing:RegisterTargets", 263 | "elasticloadbalancing:DeregisterTargets", 264 | ] 265 | resources = ["arn:${local.partition}:elasticloadbalancing:*:*:targetgroup/*/*"] 266 | } 267 | 268 | statement { 269 | actions = [ 270 | "elasticloadbalancing:SetWebAcl", 271 | "elasticloadbalancing:ModifyListener", 272 | "elasticloadbalancing:AddListenerCertificates", 273 | "elasticloadbalancing:RemoveListenerCertificates", 274 | "elasticloadbalancing:ModifyRule", 275 | "elasticloadbalancing:SetRulePriorities" 276 | ] 277 | resources = ["*"] 278 | } 279 | } 280 | 281 | locals { 282 | aws_lb_controller_policy_name = coalesce(var.aws_lb_controller_policy_name, "${var.policy_name_prefix}LoadBalancerController") 283 | } 284 | 285 | resource "aws_iam_policy" "lb_controller" { 286 | count = var.create && var.attach_aws_lb_controller_policy ? 1 : 0 287 | 288 | name = var.use_name_prefix ? null : local.aws_lb_controller_policy_name 289 | name_prefix = var.use_name_prefix ? "${local.aws_lb_controller_policy_name}-" : null 290 | path = var.path 291 | description = "Permissions for AWS Load Balancer Controller" 292 | policy = data.aws_iam_policy_document.lb_controller[0].json 293 | 294 | tags = var.tags 295 | } 296 | 297 | resource "aws_iam_role_policy_attachment" "lb_controller" { 298 | count = var.create && var.attach_aws_lb_controller_policy ? 1 : 0 299 | 300 | role = aws_iam_role.this[0].name 301 | policy_arn = aws_iam_policy.lb_controller[0].arn 302 | } 303 | 304 | ################################################################################ 305 | # AWS Load Balancer Controller TargetGroup Binding Only Policy 306 | ################################################################################ 307 | 308 | # https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.7/deploy/installation/#option-b-attach-iam-policies-to-nodes 309 | 310 | data "aws_iam_policy_document" "lb_controller_targetgroup_only" { 311 | count = var.create && var.attach_aws_lb_controller_targetgroup_binding_only_policy ? 1 : 0 312 | 313 | source_policy_documents = [data.aws_iam_policy_document.base[0].json] 314 | override_policy_documents = var.override_policy_documents 315 | 316 | statement { 317 | actions = [ 318 | "ec2:DescribeVpcs", 319 | "ec2:DescribeSecurityGroups", 320 | "ec2:DescribeInstances", 321 | "ec2:AuthorizeSecurityGroupIngress", 322 | "ec2:RevokeSecurityGroupIngress", 323 | "elasticloadbalancing:DescribeTargetGroups", 324 | "elasticloadbalancing:DescribeTargetHealth", 325 | ] 326 | 327 | resources = ["*"] 328 | } 329 | 330 | statement { 331 | actions = [ 332 | "elasticloadbalancing:ModifyTargetGroup", 333 | "elasticloadbalancing:ModifyTargetGroupAttributes", 334 | "elasticloadbalancing:RegisterTargets", 335 | "elasticloadbalancing:DeregisterTargets", 336 | ] 337 | 338 | resources = var.aws_lb_controller_targetgroup_arns 339 | } 340 | } 341 | 342 | locals { 343 | aws_lb_controller_targetgroup_only_policy_name = coalesce(var.aws_lb_controller_targetgroup_only_policy_name, "${var.policy_name_prefix}LoadBalancerControllerTargetGroupOnly") 344 | } 345 | 346 | resource "aws_iam_policy" "lb_controller_targetgroup_only" { 347 | count = var.create && var.attach_aws_lb_controller_targetgroup_binding_only_policy ? 1 : 0 348 | 349 | name = var.use_name_prefix ? null : local.aws_lb_controller_targetgroup_only_policy_name 350 | name_prefix = var.use_name_prefix ? "${local.aws_lb_controller_targetgroup_only_policy_name}-" : null 351 | path = var.path 352 | description = "Permissions for AWS Load Balancer Controller with TargetGroup binding only" 353 | policy = data.aws_iam_policy_document.lb_controller_targetgroup_only[0].json 354 | 355 | tags = var.tags 356 | } 357 | 358 | resource "aws_iam_role_policy_attachment" "lb_controller_targetgroup_only" { 359 | count = var.create && var.attach_aws_lb_controller_targetgroup_binding_only_policy ? 1 : 0 360 | 361 | role = aws_iam_role.this[0].name 362 | policy_arn = aws_iam_policy.lb_controller_targetgroup_only[0].arn 363 | } 364 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [2.5.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v2.4.2...v2.5.0) (2025-11-25) 6 | 7 | ### Features 8 | 9 | * Add `ListTagsForResource` to `external-dns` policy ([#53](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/53)) ([fc63f9f](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/fc63f9fab7fb58b3e4ac53fb4404917dd603dd3a)) 10 | 11 | ## [2.4.2](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v2.4.1...v2.4.2) (2025-11-17) 12 | 13 | ### Bug Fixes 14 | 15 | * Use empty strings for metadata default values to avoid template errors ([#52](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/52)) ([2096d87](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/2096d87b65f5a2027ef018ac41852b32c8f23426)) 16 | 17 | ## [2.4.1](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v2.4.0...v2.4.1) (2025-11-13) 18 | 19 | ### Bug Fixes 20 | 21 | * Replace deprecated `name` attribute with current `region` attribute to remove warning ([#49](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/49)) ([8c41dcc](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/8c41dcc03331ae5059002de37d9c10848aa1f101)) 22 | 23 | ## [2.4.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v2.3.0...v2.4.0) (2025-11-13) 24 | 25 | ### Features 26 | 27 | * Add support for `pganalyze` ([#48](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/48)) ([1cdb405](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/1cdb4053a408068a5267dfee36221d332e1ae9d7)) 28 | 29 | ## [2.3.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v2.2.1...v2.3.0) (2025-11-12) 30 | 31 | ### Features 32 | 33 | * Add `wafv2:ListWebACLs` permission for ALB controller ([#47](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/47)) ([9117ea6](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/9117ea6624979f75366c3c46ae6de5f8e5803837)) 34 | 35 | ## [2.2.1](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v2.2.0...v2.2.1) (2025-10-21) 36 | 37 | ### Bug Fixes 38 | 39 | * Update CI workflow versions to latest ([#46](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/46)) ([1501e7f](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/1501e7fc7087e05ba257da7a487bcdc9631ab3ea)) 40 | 41 | ## [2.2.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v2.1.0...v2.2.0) (2025-10-15) 42 | 43 | 44 | ### Features 45 | 46 | * Add support to `ebs-csi` policy for volume clones ([#45](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/45)) ([4ec0d54](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/4ec0d543b7a2a50c3dd5bb58f5eb5ca7f74b86b3)) 47 | 48 | ## [2.1.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v2.0.0...v2.1.0) (2025-10-14) 49 | 50 | 51 | ### Features 52 | 53 | * Add Velero kms keys policy ([#44](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/44)) ([f60f7b3](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/f60f7b3c188aba5c6f10edefaedab3a077b37569)) 54 | 55 | ## [2.0.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.12.1...v2.0.0) (2025-08-05) 56 | 57 | 58 | ### ⚠ BREAKING CHANGES 59 | 60 | * Update Terraform and AWS provider versions to `1.5.7` and `6.2` respectively (#40) 61 | 62 | ### Features 63 | 64 | * Update Terraform and AWS provider versions to `1.5.7` and `6.2` respectively ([#40](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/40)) ([df2656b](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/df2656b80afbb64c08e68765be144f732d98aa81)) 65 | 66 | ## [1.12.1](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.12.0...v1.12.1) (2025-07-05) 67 | 68 | 69 | ### Bug Fixes 70 | 71 | * Update IAM policy for External Secrets ([#38](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/38)) ([8083c02](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/8083c02f7337c1a827118b5fed8d63745a8507bd)) 72 | 73 | ## [1.12.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.11.0...v1.12.0) (2025-06-03) 74 | 75 | 76 | ### Features 77 | 78 | * Update AWS Load Balancer controller policy to match v2.13 of the upstream project ([#36](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/36)) ([b1898a2](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/b1898a2709a1cb56fea5d609038fff61bba7dd78)) 79 | 80 | ## [1.11.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.10.0...v1.11.0) (2025-03-12) 81 | 82 | 83 | ### Features 84 | 85 | * Update IAM permissions for load balancer controller v2.12.0 ([#33](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/33)) ([36379bc](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/36379bcb3b5b62038e7936936d1bbedf28936157)) 86 | 87 | ## [1.10.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.9.1...v1.10.0) (2025-01-29) 88 | 89 | 90 | ### Features 91 | 92 | * Add `ec2:DescribeSubnets` policy to `aws-vpc-cni` ([#29](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/29)) ([2f1907b](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/2f1907baf15677a0efe1afc4ba7075b7525acb9e)) 93 | 94 | ## [1.9.1](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.9.0...v1.9.1) (2025-01-09) 95 | 96 | 97 | ### Bug Fixes 98 | 99 | * Fix IAM policy for External Secrets ([#28](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/28)) ([9bc8032](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/9bc80322946b7f047e36129a1ea293d460ba66a4)) 100 | 101 | ## [1.9.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.8.0...v1.9.0) (2024-12-27) 102 | 103 | 104 | ### Features 105 | 106 | * Update policies for AWS LBC v2.11.0 ([#27](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/27)) ([f5c4932](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/f5c4932da8586d90ed57179aa1c9270394b0ac81)) 107 | 108 | ## [1.8.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.7.0...v1.8.0) (2024-12-27) 109 | 110 | 111 | ### Features 112 | 113 | * Update policie for External Secrets 0.12.1 ([#26](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/26)) ([b63aaf1](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/b63aaf1edeee9e1e2eaff7d3a9503971c09fc47e)) 114 | 115 | ## [1.7.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.6.1...v1.7.0) (2024-11-11) 116 | 117 | 118 | ### Features 119 | 120 | * Add `ec2:GetSecurityGroupsForVpc` for AWS LB Controller `v2.10.0` ([#25](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/25)) ([dfef351](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/dfef351722163fc20212291db5025dc62a2d2ec0)) 121 | 122 | ## [1.6.1](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.6.0...v1.6.1) (2024-10-22) 123 | 124 | 125 | ### Bug Fixes 126 | 127 | * Use dynamic partition value ([#23](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/23)) ([85f71d9](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/85f71d9c3a1d590407c0c358a012818e8efee66f)) 128 | 129 | ## [1.6.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.5.0...v1.6.0) (2024-10-21) 130 | 131 | 132 | ### Features 133 | 134 | * Update AWS EBS CSI Driver IAM Policy ([#22](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/22)) ([18e6434](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/18e64340b3eb298e76676c6bdeff8292bd5ef510)) 135 | 136 | 137 | ### Bug Fixes 138 | 139 | * Update CI workflow versions to latest ([#21](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/21)) ([2f8cf45](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/2f8cf453b1d9e2ed9b7ad04a79cf5b409cda9cd3)) 140 | 141 | ## [1.5.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.4.3...v1.5.0) (2024-10-05) 142 | 143 | 144 | ### Features 145 | 146 | * Update IAM policy for AWS Load Balancer Controller to support Listener Attributes ([#19](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/19)) ([ef9c1d7](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/ef9c1d76f49484a3c71cbd66ccd25b68078dc278)) 147 | 148 | ## [1.4.3](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.4.2...v1.4.3) (2024-10-01) 149 | 150 | 151 | ### Bug Fixes 152 | 153 | * Add required S3 PutObjectTagging permission to IAM policy ([#17](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/17)) ([def5c02](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/def5c02bf0c662d8a52cd4da1c671b3060231296)) 154 | 155 | ## [1.4.2](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.4.1...v1.4.2) (2024-09-25) 156 | 157 | 158 | ### Bug Fixes 159 | 160 | * Ensure FSX IAM Policy Permits Updating File Systems ([#16](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/16)) ([c9d93c3](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/c9d93c3ad016697d8b97e3d9c46f17e7b3e57b84)) 161 | 162 | ## [1.4.1](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.4.0...v1.4.1) (2024-09-05) 163 | 164 | 165 | ### Bug Fixes 166 | 167 | * Change `association_defaults` type from `map(string)` to `any` to support tags ([#15](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/15)) ([85f2516](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/85f25165c7a115738d053ff93fa24b3d3701fb4b)) 168 | 169 | ## [1.4.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.3.0...v1.4.0) (2024-08-07) 170 | 171 | 172 | ### Features 173 | 174 | * Add cloudwatch logs policy to vpc-cni for networkpolicy logging ([#13](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/13)) ([a5da73e](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/a5da73e26a8d4ca46f76ea5e4e0c57479a451837)) 175 | 176 | ## [1.3.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.2.1...v1.3.0) (2024-07-21) 177 | 178 | 179 | ### Features 180 | 181 | * Add support for specifying assume role conditions ([#12](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/12)) ([5249afc](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/5249afcf2c5c8f7347c48d4bc8caab193dcf5e20)) 182 | 183 | ## [1.2.1](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.2.0...v1.2.1) (2024-05-30) 184 | 185 | 186 | ### Bug Fixes 187 | 188 | * TargetGroup Binding only policy requires policies for SecurityGroup ([#10](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/10)) ([ba34af4](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/ba34af404af6dd45a387dc8689e07183667afc58)) 189 | 190 | ## [1.2.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.1.0...v1.2.0) (2024-04-02) 191 | 192 | 193 | ### Features 194 | 195 | * Add fast snapshot restore policy to ebs csi role ([#5](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/5)) ([10f90d6](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/10f90d6d92e23b66520a92d9f80870d008825fdd)) 196 | 197 | ## [1.1.0](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/compare/v1.0.0...v1.1.0) (2024-03-21) 198 | 199 | 200 | ### Features 201 | 202 | * Add support for creating pod identity associations ([#4](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/issues/4)) ([98c5bdf](https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity/commit/98c5bdf103094e907315c980981841efae26ae2b)) 203 | -------------------------------------------------------------------------------- /examples/complete/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = local.region 3 | } 4 | 5 | data "aws_availability_zones" "available" {} 6 | 7 | locals { 8 | region = "eu-west-1" 9 | name = "pod-id-ex-${basename(path.cwd)}" 10 | 11 | vpc_cidr = "10.0.0.0/16" 12 | azs = slice(data.aws_availability_zones.available.names, 0, 3) 13 | 14 | tags = { 15 | Name = local.name 16 | Example = local.name 17 | Repository = "https://github.com/terraform-aws-modules/terraform-aws-eks-pod-identity" 18 | } 19 | } 20 | 21 | ################################################################################ 22 | # EKS Pod Identity Module 23 | ################################################################################ 24 | 25 | module "custom_pod_identity" { 26 | source = "../../" 27 | 28 | name = local.name 29 | 30 | attach_custom_policy = true 31 | source_policy_documents = [data.aws_iam_policy_document.source.json] 32 | override_policy_documents = [data.aws_iam_policy_document.override.json] 33 | 34 | additional_policy_arns = { 35 | AmazonEKS_CNI_Policy = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" 36 | additional = aws_iam_policy.additional.arn 37 | } 38 | 39 | trust_policy_conditions = [ 40 | { 41 | test = "StringEquals" 42 | variable = "aws:PrincipalOrgID" 43 | values = ["o-1234567890"] 44 | } 45 | ] 46 | 47 | associations = { 48 | ex-one = { 49 | cluster_name = module.eks_one.cluster_name 50 | namespace = "custom" 51 | service_account = "custom" 52 | } 53 | ex-two = { 54 | cluster_name = module.eks_two.cluster_name 55 | namespace = "custom" 56 | service_account = "custom" 57 | } 58 | } 59 | 60 | tags = local.tags 61 | } 62 | 63 | module "aws_gateway_controller_pod_identity" { 64 | source = "../../" 65 | 66 | name = "aws-gateway-controller" 67 | 68 | attach_aws_gateway_controller_policy = true 69 | 70 | # Pod Identity Associations 71 | association_defaults = { 72 | namespace = "aws-application-networking-system" 73 | service_account = "gateway-api-controller" 74 | tags = { App = "Example" } 75 | } 76 | 77 | associations = { 78 | ex-one = { 79 | cluster_name = module.eks_one.cluster_name 80 | } 81 | ex-two = { 82 | cluster_name = module.eks_two.cluster_name 83 | } 84 | } 85 | 86 | tags = local.tags 87 | } 88 | 89 | module "cert_manager_pod_identity" { 90 | source = "../../" 91 | 92 | name = "cert-manager" 93 | 94 | attach_cert_manager_policy = true 95 | cert_manager_hosted_zone_arns = ["arn:aws:route53:::hostedzone/IClearlyMadeThisUp"] 96 | 97 | # Pod Identity Associations 98 | association_defaults = { 99 | namespace = "cert-manager" 100 | service_account = "cert-manager" 101 | } 102 | 103 | associations = { 104 | ex-one = { 105 | cluster_name = module.eks_one.cluster_name 106 | } 107 | ex-two = { 108 | cluster_name = module.eks_two.cluster_name 109 | } 110 | } 111 | 112 | tags = local.tags 113 | } 114 | 115 | module "aws_cloudwatch_observability_pod_identity" { 116 | source = "../../" 117 | 118 | name = "aws-cloudwatch-observability" 119 | 120 | attach_aws_cloudwatch_observability_policy = true 121 | 122 | # Pod Identity Associations 123 | association_defaults = { 124 | namespace = "amazon-cloudwatch" 125 | service_account = "cloudwatch-agent" 126 | } 127 | 128 | associations = { 129 | ex-one = { 130 | cluster_name = module.eks_one.cluster_name 131 | } 132 | ex-two = { 133 | cluster_name = module.eks_two.cluster_name 134 | } 135 | } 136 | 137 | tags = local.tags 138 | } 139 | 140 | module "cluster_autoscaler_pod_identity" { 141 | source = "../../" 142 | 143 | name = "cluster-autoscaler" 144 | 145 | attach_cluster_autoscaler_policy = true 146 | cluster_autoscaler_cluster_names = ["foo"] 147 | 148 | # Pod Identity Associations 149 | association_defaults = { 150 | namespace = "kube-system" 151 | service_account = "cluster-autoscaler-sa" 152 | } 153 | 154 | associations = { 155 | ex-one = { 156 | cluster_name = module.eks_one.cluster_name 157 | } 158 | ex-two = { 159 | cluster_name = module.eks_two.cluster_name 160 | } 161 | } 162 | 163 | tags = local.tags 164 | } 165 | 166 | module "aws_ebs_csi_pod_identity" { 167 | source = "../../" 168 | 169 | name = "aws-ebs-csi" 170 | 171 | attach_aws_ebs_csi_policy = true 172 | aws_ebs_csi_kms_arns = ["arn:aws:kms:*:*:key/1234abcd-12ab-34cd-56ef-1234567890ab"] 173 | 174 | # Pod Identity Associations 175 | association_defaults = { 176 | namespace = "kube-system" 177 | service_account = "ebs-csi-controller-sa" 178 | } 179 | 180 | associations = { 181 | ex-one = { 182 | cluster_name = module.eks_one.cluster_name 183 | } 184 | ex-two = { 185 | cluster_name = module.eks_two.cluster_name 186 | } 187 | } 188 | 189 | tags = local.tags 190 | } 191 | 192 | module "aws_efs_csi_pod_identity" { 193 | source = "../../" 194 | 195 | name = "aws-efs-csi" 196 | 197 | attach_aws_efs_csi_policy = true 198 | 199 | # Pod Identity Associations 200 | association_defaults = { 201 | namespace = "kube-system" 202 | service_account = "efs-csi-controller-sa" 203 | } 204 | 205 | associations = { 206 | ex-one = { 207 | cluster_name = module.eks_one.cluster_name 208 | } 209 | ex-two = { 210 | cluster_name = module.eks_two.cluster_name 211 | } 212 | } 213 | 214 | tags = local.tags 215 | } 216 | 217 | module "external_dns_pod_identity" { 218 | source = "../../" 219 | 220 | name = "external-dns" 221 | 222 | attach_external_dns_policy = true 223 | external_dns_hosted_zone_arns = ["arn:aws:route53:::hostedzone/IClearlyMadeThisUp"] 224 | 225 | # Pod Identity Associations 226 | association_defaults = { 227 | namespace = "external-dns" 228 | service_account = "external-dns-sa" 229 | } 230 | 231 | associations = { 232 | ex-one = { 233 | cluster_name = module.eks_one.cluster_name 234 | } 235 | ex-two = { 236 | cluster_name = module.eks_two.cluster_name 237 | } 238 | } 239 | 240 | tags = local.tags 241 | } 242 | 243 | module "external_secrets_pod_identity" { 244 | source = "../../" 245 | 246 | name = "external-secrets" 247 | 248 | attach_external_secrets_policy = true 249 | external_secrets_ssm_parameter_arns = ["arn:aws:ssm:*:*:parameter/foo"] 250 | external_secrets_secrets_manager_arns = ["arn:aws:secretsmanager:*:*:secret:bar"] 251 | external_secrets_kms_key_arns = ["arn:aws:kms:*:*:key/1234abcd-12ab-34cd-56ef-1234567890ab"] 252 | external_secrets_create_permission = true 253 | 254 | # Pod Identity Associations 255 | association_defaults = { 256 | namespace = "external-secrets" 257 | service_account = "external-secrets-sa" 258 | } 259 | 260 | associations = { 261 | ex-one = { 262 | cluster_name = module.eks_one.cluster_name 263 | } 264 | ex-two = { 265 | cluster_name = module.eks_two.cluster_name 266 | } 267 | } 268 | 269 | tags = local.tags 270 | } 271 | 272 | module "aws_fsx_lustre_csi_pod_identity" { 273 | source = "../../" 274 | 275 | name = "aws-fsx-lustre-csi" 276 | 277 | attach_aws_fsx_lustre_csi_policy = true 278 | aws_fsx_lustre_csi_service_role_arns = ["arn:aws:iam::*:role/aws-service-role/s3.data-source.lustre.fsx.amazonaws.com/*"] 279 | 280 | # Pod Identity Associations 281 | association_defaults = { 282 | namespace = "kube-system" 283 | service_account = "fsx-csi-controller-sa" 284 | } 285 | 286 | associations = { 287 | ex-one = { 288 | cluster_name = module.eks_one.cluster_name 289 | } 290 | ex-two = { 291 | cluster_name = module.eks_two.cluster_name 292 | } 293 | } 294 | 295 | tags = local.tags 296 | } 297 | 298 | module "aws_lb_controller_pod_identity" { 299 | source = "../../" 300 | 301 | name = "aws-lbc" 302 | 303 | attach_aws_lb_controller_policy = true 304 | 305 | # Pod Identity Associations 306 | association_defaults = { 307 | namespace = "kube-system" 308 | service_account = "aws-load-balancer-controller-sa" 309 | } 310 | 311 | associations = { 312 | ex-one = { 313 | cluster_name = module.eks_one.cluster_name 314 | } 315 | ex-two = { 316 | cluster_name = module.eks_two.cluster_name 317 | } 318 | } 319 | 320 | tags = local.tags 321 | } 322 | 323 | module "aws_lb_controller_targetgroup_binding_only_pod_identity" { 324 | source = "../../" 325 | 326 | name = "aws-lbc-targetgroup-binding-only" 327 | 328 | attach_aws_lb_controller_targetgroup_binding_only_policy = true 329 | aws_lb_controller_targetgroup_arns = ["arn:aws:elasticloadbalancing:*:*:targetgroup/foo/bar"] 330 | 331 | # Pod Identity Associations 332 | association_defaults = { 333 | namespace = "kube-system" 334 | service_account = "aws-load-balancer-controller-tgb-sa" 335 | } 336 | 337 | associations = { 338 | ex-one = { 339 | cluster_name = module.eks_one.cluster_name 340 | } 341 | ex-two = { 342 | cluster_name = module.eks_two.cluster_name 343 | } 344 | } 345 | 346 | tags = local.tags 347 | } 348 | 349 | module "aws_appmesh_controller_pod_identity" { 350 | source = "../../" 351 | 352 | name = "aws-appmesh-controller" 353 | 354 | attach_aws_appmesh_controller_policy = true 355 | 356 | # Pod Identity Associations 357 | association_defaults = { 358 | namespace = "appmesh-system" 359 | service_account = "appmesh-controller" 360 | } 361 | 362 | associations = { 363 | ex-one = { 364 | cluster_name = module.eks_one.cluster_name 365 | } 366 | ex-two = { 367 | cluster_name = module.eks_two.cluster_name 368 | } 369 | } 370 | 371 | tags = local.tags 372 | } 373 | 374 | module "aws_appmesh_envoy_proxy_pod_identity" { 375 | source = "../../" 376 | 377 | name = "aws-appmesh-envoy-proxy" 378 | 379 | attach_aws_appmesh_envoy_proxy_policy = true 380 | 381 | # Pod Identity Associations 382 | association_defaults = { 383 | namespace = "appmesh-system" 384 | service_account = "envoy-proxy" 385 | } 386 | 387 | associations = { 388 | ex-one = { 389 | cluster_name = module.eks_one.cluster_name 390 | } 391 | ex-two = { 392 | cluster_name = module.eks_two.cluster_name 393 | } 394 | } 395 | 396 | tags = local.tags 397 | } 398 | 399 | module "amazon_managed_service_prometheus_pod_identity" { 400 | source = "../../" 401 | 402 | name = "amazon-managed-service-prometheus" 403 | 404 | attach_amazon_managed_service_prometheus_policy = true 405 | amazon_managed_service_prometheus_workspace_arns = ["arn:aws:prometheus:*:*:workspace/foo"] 406 | 407 | # Pod Identity Associations 408 | association_defaults = { 409 | namespace = "prometheus" 410 | service_account = "prometheus" 411 | } 412 | 413 | associations = { 414 | ex-one = { 415 | cluster_name = module.eks_one.cluster_name 416 | } 417 | ex-two = { 418 | cluster_name = module.eks_two.cluster_name 419 | } 420 | } 421 | 422 | tags = local.tags 423 | } 424 | 425 | module "mountpoint_s3_csi_pod_identity" { 426 | source = "../../" 427 | 428 | name = "mountpoint-s3-csi" 429 | 430 | attach_mountpoint_s3_csi_policy = true 431 | mountpoint_s3_csi_bucket_arns = ["arn:aws:s3:::mountpoint-s3"] 432 | mountpoint_s3_csi_bucket_path_arns = ["arn:aws:s3:::mountpoint-s3/example/*"] 433 | 434 | # Pod Identity Associations 435 | association_defaults = { 436 | namespace = "kube-system" 437 | service_account = "s3-csi-driver-sa" 438 | } 439 | 440 | associations = { 441 | ex-one = { 442 | cluster_name = module.eks_one.cluster_name 443 | } 444 | ex-two = { 445 | cluster_name = module.eks_two.cluster_name 446 | } 447 | } 448 | 449 | tags = local.tags 450 | } 451 | 452 | module "aws_node_termination_handler_pod_identity" { 453 | source = "../../" 454 | 455 | name = "aws-node-termination-handler" 456 | 457 | attach_aws_node_termination_handler_policy = true 458 | aws_node_termination_handler_sqs_queue_arns = ["arn:aws:sqs:*:*:eks-node-termination-handler"] 459 | 460 | # Pod Identity Associations 461 | association_defaults = { 462 | namespace = "aws-node-termination-handler" 463 | service_account = "aws-node-termination-handler-sa" 464 | } 465 | 466 | associations = { 467 | ex-one = { 468 | cluster_name = module.eks_one.cluster_name 469 | } 470 | ex-two = { 471 | cluster_name = module.eks_two.cluster_name 472 | } 473 | } 474 | 475 | tags = local.tags 476 | } 477 | 478 | module "aws_privateca_issuer_pod_identity" { 479 | source = "../../" 480 | 481 | name = "aws-privateca-issuer" 482 | 483 | attach_aws_privateca_issuer_policy = true 484 | aws_privateca_issuer_acmca_arns = ["arn:aws:acm-pca:*:*:certificate-authority/foo"] 485 | 486 | # Pod Identity Associations 487 | association_defaults = { 488 | namespace = "cert-manager" 489 | service_account = "aws-privateca-issuer-sa" 490 | } 491 | 492 | associations = { 493 | ex-one = { 494 | cluster_name = module.eks_one.cluster_name 495 | } 496 | ex-two = { 497 | cluster_name = module.eks_two.cluster_name 498 | } 499 | } 500 | 501 | tags = local.tags 502 | } 503 | 504 | module "pganalyze_pod_identity" { 505 | source = "../../" 506 | 507 | name = "pganalyze" 508 | 509 | attach_pganalyze_policy = true 510 | 511 | # Pod Identity Associations 512 | association_defaults = { 513 | namespace = "default" 514 | service_account = "pganalyze-service-account" 515 | } 516 | 517 | associations = { 518 | ex-one = { 519 | cluster_name = module.eks_one.cluster_name 520 | } 521 | ex-two = { 522 | cluster_name = module.eks_two.cluster_name 523 | } 524 | } 525 | 526 | tags = local.tags 527 | } 528 | 529 | module "velero_pod_identity" { 530 | source = "../../" 531 | 532 | name = "velero" 533 | 534 | attach_velero_policy = true 535 | velero_s3_bucket_arns = ["arn:aws:s3:::velero-backups"] 536 | velero_s3_bucket_path_arns = ["arn:aws:s3:::velero-backups/example/*"] 537 | velero_kms_arns = ["arn:aws:kms:*:*:key/1234abcd-12ab-34cd-56ef-1234567890ab"] 538 | 539 | # Pod Identity Associations 540 | association_defaults = { 541 | namespace = "velero" 542 | service_account = "velero-server" 543 | } 544 | 545 | associations = { 546 | ex-one = { 547 | cluster_name = module.eks_one.cluster_name 548 | } 549 | ex-two = { 550 | cluster_name = module.eks_two.cluster_name 551 | } 552 | } 553 | 554 | tags = local.tags 555 | } 556 | 557 | module "aws_vpc_cni_ipv4_pod_identity" { 558 | source = "../../" 559 | 560 | name = "aws-vpc-cni-ipv4" 561 | 562 | attach_aws_vpc_cni_policy = true 563 | aws_vpc_cni_enable_ipv4 = true 564 | 565 | # Pod Identity Associations 566 | association_defaults = { 567 | namespace = "kube-system" 568 | service_account = "aws-node" 569 | } 570 | 571 | associations = { 572 | ex-one = { 573 | cluster_name = module.eks_one.cluster_name 574 | } 575 | ex-two = { 576 | cluster_name = module.eks_two.cluster_name 577 | } 578 | } 579 | 580 | tags = local.tags 581 | } 582 | 583 | module "aws_vpc_cni_ipv6_pod_identity" { 584 | source = "../../" 585 | 586 | name = "aws-vpc-cni-ipv6" 587 | 588 | attach_aws_vpc_cni_policy = true 589 | aws_vpc_cni_enable_ipv6 = true 590 | 591 | # Pod Identity Associations 592 | association_defaults = { 593 | namespace = "kube-system" 594 | service_account = "aws-node-ipv6" 595 | } 596 | 597 | associations = { 598 | ex-one = { 599 | cluster_name = module.eks_one.cluster_name 600 | } 601 | ex-two = { 602 | cluster_name = module.eks_two.cluster_name 603 | } 604 | } 605 | 606 | tags = local.tags 607 | } 608 | 609 | module "disabled" { 610 | source = "../../" 611 | 612 | create = false 613 | } 614 | 615 | ################################################################################ 616 | # Supporting Resources 617 | ################################################################################ 618 | 619 | resource "aws_iam_policy" "additional" { 620 | name = "${local.name}-additional" 621 | description = "Additional test policy" 622 | 623 | policy = jsonencode({ 624 | Version = "2012-10-17" 625 | Statement = [ 626 | { 627 | Action = [ 628 | "ec2:Describe*", 629 | ] 630 | Effect = "Allow" 631 | Resource = "*" 632 | }, 633 | ] 634 | }) 635 | 636 | tags = local.tags 637 | } 638 | 639 | data "aws_iam_policy_document" "source" { 640 | statement { 641 | actions = ["s3:GetBucketLocation"] 642 | resources = ["arn:aws:s3:::*"] 643 | } 644 | } 645 | 646 | data "aws_iam_policy_document" "override" { 647 | statement { 648 | effect = "Deny" 649 | 650 | actions = ["s3:*"] 651 | resources = ["*"] 652 | } 653 | } 654 | 655 | module "eks_one" { 656 | source = "terraform-aws-modules/eks/aws" 657 | version = "~> 21.0" 658 | 659 | name = "${local.name}-one" 660 | 661 | vpc_id = module.vpc.vpc_id 662 | subnet_ids = module.vpc.private_subnets 663 | 664 | tags = local.tags 665 | } 666 | 667 | module "eks_two" { 668 | source = "terraform-aws-modules/eks/aws" 669 | version = "~> 21.0" 670 | 671 | name = "${local.name}-two" 672 | 673 | vpc_id = module.vpc.vpc_id 674 | subnet_ids = module.vpc.private_subnets 675 | 676 | tags = local.tags 677 | } 678 | 679 | module "vpc" { 680 | source = "terraform-aws-modules/vpc/aws" 681 | version = "~> 6.0" 682 | 683 | name = local.name 684 | cidr = local.vpc_cidr 685 | 686 | azs = local.azs 687 | private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] 688 | 689 | enable_nat_gateway = false 690 | 691 | tags = local.tags 692 | } 693 | -------------------------------------------------------------------------------- /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 "region" { 8 | description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration" 9 | type = string 10 | default = null 11 | } 12 | 13 | variable "tags" { 14 | description = "A map of tags to add to all resources" 15 | type = map(string) 16 | default = {} 17 | } 18 | 19 | ################################################################################ 20 | # IAM Role Trust Policy 21 | ################################################################################ 22 | 23 | variable "trust_policy_conditions" { 24 | description = "A list of conditions to add to the role trust policy" 25 | type = list(object({ 26 | test = string 27 | values = list(string) 28 | variable = string 29 | })) 30 | default = [] 31 | } 32 | 33 | variable "trust_policy_statements" { 34 | description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) for the role trust policy" 35 | type = list(object({ 36 | sid = optional(string) 37 | actions = optional(list(string)) 38 | not_actions = optional(list(string)) 39 | effect = optional(string) 40 | resources = optional(list(string)) 41 | not_resources = optional(list(string)) 42 | principals = optional(list(object({ 43 | type = string 44 | identifiers = list(string) 45 | }))) 46 | not_principals = optional(list(object({ 47 | type = string 48 | identifiers = list(string) 49 | }))) 50 | condition = optional(list(object({ 51 | test = string 52 | values = list(string) 53 | variable = string 54 | }))) 55 | })) 56 | default = null 57 | } 58 | 59 | ################################################################################ 60 | # IAM Role 61 | ################################################################################ 62 | 63 | variable "name" { 64 | description = "Name of IAM role" 65 | type = string 66 | default = "" 67 | } 68 | 69 | variable "use_name_prefix" { 70 | description = "Determines whether the role name and policy name(s) are used as a prefix" 71 | type = string 72 | default = true 73 | } 74 | 75 | variable "path" { 76 | description = "Path of IAM role" 77 | type = string 78 | default = "/" 79 | } 80 | 81 | variable "description" { 82 | description = "IAM Role description" 83 | type = string 84 | default = null 85 | } 86 | 87 | variable "max_session_duration" { 88 | description = "Maximum CLI/API session duration in seconds between 3600 and 43200" 89 | type = number 90 | default = null 91 | } 92 | 93 | variable "permissions_boundary_arn" { 94 | description = "Permissions boundary ARN to use for IAM role" 95 | type = string 96 | default = null 97 | } 98 | 99 | variable "additional_policy_arns" { 100 | description = "ARNs of additional policies to attach to the IAM role" 101 | type = map(string) 102 | default = {} 103 | } 104 | 105 | ################################################################################ 106 | # Pod Identity Association 107 | ################################################################################ 108 | 109 | variable "association_defaults" { 110 | description = "Default values used across all Pod Identity associations created unless a more specific value is provided" 111 | type = object({ 112 | cluster_name = optional(string) 113 | disable_session_tags = optional(bool) 114 | namespace = optional(string) 115 | service_account = optional(string) 116 | role_arn = optional(string) 117 | target_role_arn = optional(string) 118 | tags = optional(map(string), {}) 119 | }) 120 | default = {} 121 | } 122 | 123 | variable "associations" { 124 | description = "Map of Pod Identity associations to be created (map of maps)" 125 | type = map(object({ 126 | cluster_name = optional(string) 127 | disable_session_tags = optional(bool) 128 | namespace = optional(string) 129 | service_account = optional(string) 130 | role_arn = optional(string) 131 | target_role_arn = optional(string) 132 | tags = optional(map(string), {}) 133 | })) 134 | default = {} 135 | } 136 | 137 | ################################################################################ 138 | # Policies 139 | ################################################################################ 140 | 141 | variable "source_policy_documents" { 142 | description = "List of IAM policy documents that are merged together into the exported document" 143 | type = list(string) 144 | default = [] 145 | } 146 | 147 | variable "override_policy_documents" { 148 | description = "List of IAM policy documents that are merged together into the exported document" 149 | type = list(string) 150 | default = [] 151 | } 152 | 153 | variable "policy_statements" { 154 | 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" 155 | type = list(object({ 156 | sid = optional(string) 157 | actions = optional(list(string)) 158 | not_actions = optional(list(string)) 159 | effect = optional(string) 160 | resources = optional(list(string)) 161 | not_resources = optional(list(string)) 162 | principals = optional(list(object({ 163 | type = string 164 | identifiers = list(string) 165 | }))) 166 | not_principals = optional(list(object({ 167 | type = string 168 | identifiers = list(string) 169 | }))) 170 | condition = optional(list(object({ 171 | test = string 172 | values = list(string) 173 | variable = string 174 | }))) 175 | })) 176 | default = null 177 | } 178 | 179 | variable "policy_name_prefix" { 180 | description = "IAM policy name prefix" 181 | type = string 182 | default = "AmazonEKS_" 183 | } 184 | 185 | # Custom policy 186 | variable "attach_custom_policy" { 187 | description = "Determines whether to attach the custom IAM policy to the role" 188 | type = bool 189 | default = false 190 | } 191 | 192 | variable "custom_policy_description" { 193 | description = "Description of the custom IAM policy" 194 | type = string 195 | default = "Custom IAM Policy" 196 | } 197 | 198 | # Amazon Managed Service for Prometheus 199 | variable "attach_amazon_managed_service_prometheus_policy" { 200 | description = "Determines whether to attach the Amazon Managed Service for Prometheus IAM policy to the role" 201 | type = bool 202 | default = false 203 | } 204 | 205 | variable "amazon_managed_service_prometheus_policy_name" { 206 | description = "Custom name of the Amazon Managed Service for Prometheus IAM policy" 207 | type = string 208 | default = null 209 | } 210 | 211 | variable "amazon_managed_service_prometheus_workspace_arns" { 212 | description = "List of AMP Workspace ARNs to read and write metrics" 213 | type = list(string) 214 | default = [] 215 | } 216 | 217 | # AWS Appmesh Controller 218 | variable "attach_aws_appmesh_controller_policy" { 219 | description = "Determines whether to attach the AppMesh Controller policy to the role" 220 | type = bool 221 | default = false 222 | } 223 | 224 | variable "appmesh_controller_policy_name" { 225 | description = "Custom name of the AppMesh Controller IAM policy" 226 | type = string 227 | default = null 228 | } 229 | 230 | # AWS Cloudwatch Observability Agent 231 | variable "attach_aws_cloudwatch_observability_policy" { 232 | description = "Determines whether to attach the AWS Cloudwatch Observability IAM policy to the role" 233 | type = bool 234 | default = false 235 | } 236 | 237 | # AWS Appmesh envoy proxy 238 | variable "attach_aws_appmesh_envoy_proxy_policy" { 239 | description = "Determines whether to attach the AppMesh Envoy Proxy policy to the role" 240 | type = bool 241 | default = false 242 | } 243 | 244 | variable "appmesh_envoy_proxy_policy_name" { 245 | description = "Custom name of the AppMesh Envoy Proxy IAM policy" 246 | type = string 247 | default = null 248 | } 249 | 250 | # AWS EBS CSI 251 | variable "attach_aws_ebs_csi_policy" { 252 | description = "Determines whether to attach the EBS CSI IAM policy to the role" 253 | type = bool 254 | default = false 255 | } 256 | 257 | variable "aws_ebs_csi_policy_name" { 258 | description = "Custom name of the EBS CSI IAM policy" 259 | type = string 260 | default = null 261 | } 262 | 263 | variable "aws_ebs_csi_kms_arns" { 264 | description = "KMS key ARNs to allow EBS CSI to manage encrypted volumes" 265 | type = list(string) 266 | default = [] 267 | } 268 | 269 | # AWS EFS CSI 270 | variable "attach_aws_efs_csi_policy" { 271 | description = "Determines whether to attach the EFS CSI IAM policy to the role" 272 | type = bool 273 | default = false 274 | } 275 | 276 | variable "aws_efs_csi_policy_name" { 277 | description = "Custom name of the EFS CSI IAM policy" 278 | type = string 279 | default = null 280 | } 281 | 282 | # AWS FSx Lustre CSI 283 | variable "attach_aws_fsx_lustre_csi_policy" { 284 | description = "Determines whether to attach the FSx for Lustre CSI Driver IAM policy to the role" 285 | type = bool 286 | default = false 287 | } 288 | 289 | variable "aws_fsx_lustre_csi_policy_name" { 290 | description = "Custom name of the FSx for Lustre CSI Driver IAM policy" 291 | type = string 292 | default = null 293 | } 294 | 295 | variable "aws_fsx_lustre_csi_service_role_arns" { 296 | description = "Service role ARNs to allow FSx for Lustre CSI create and manage FSX for Lustre service linked roles" 297 | type = list(string) 298 | default = [] 299 | } 300 | 301 | # AWS Gateway Controller 302 | variable "attach_aws_gateway_controller_policy" { 303 | description = "Determines whether to attach the AWS Gateway Controller IAM policy to the role" 304 | type = bool 305 | default = false 306 | } 307 | 308 | variable "aws_gateway_controller_policy_name" { 309 | description = "Custom name of the AWS Gateway Controller IAM policy" 310 | type = string 311 | default = null 312 | } 313 | 314 | # AWS Load Balancer Controller 315 | variable "attach_aws_lb_controller_policy" { 316 | description = "Determines whether to attach the AWS Load Balancer Controller policy to the role" 317 | type = bool 318 | default = false 319 | } 320 | 321 | variable "aws_lb_controller_policy_name" { 322 | description = "Custom name of the AWS Load Balancer Controller IAM policy" 323 | type = string 324 | default = null 325 | } 326 | 327 | # AWS Load Balancer Controller TargetGroup Binding Only 328 | variable "attach_aws_lb_controller_targetgroup_binding_only_policy" { 329 | description = "Determines whether to attach the AWS Load Balancer Controller policy for the TargetGroupBinding only" 330 | type = bool 331 | default = false 332 | } 333 | 334 | variable "aws_lb_controller_targetgroup_only_policy_name" { 335 | description = "Custom name of the AWS Load Balancer Controller IAM policy for the TargetGroupBinding only" 336 | type = string 337 | default = null 338 | } 339 | 340 | variable "aws_lb_controller_targetgroup_arns" { 341 | description = "List of Target groups ARNs using Load Balancer Controller" 342 | type = list(string) 343 | default = [] 344 | } 345 | 346 | # AWS Node termination handler 347 | variable "attach_aws_node_termination_handler_policy" { 348 | description = "Determines whether to attach the Node Termination Handler policy to the role" 349 | type = bool 350 | default = false 351 | } 352 | 353 | variable "aws_node_termination_handler_policy_name" { 354 | description = "Custom name of the Node Termination Handler IAM policy" 355 | type = string 356 | default = null 357 | } 358 | 359 | variable "aws_node_termination_handler_sqs_queue_arns" { 360 | description = "List of SQS ARNs that contain node termination events" 361 | type = list(string) 362 | default = [] 363 | } 364 | 365 | # AWS Private CA Issuer 366 | variable "attach_aws_privateca_issuer_policy" { 367 | description = "Determines whether to attach the AWS Private CA Issuer IAM policy to the role" 368 | type = bool 369 | default = false 370 | } 371 | 372 | variable "aws_privateca_issuer_policy_name" { 373 | description = "Custom name of the AWS Private CA Issuer IAM policy" 374 | type = string 375 | default = null 376 | } 377 | 378 | variable "aws_privateca_issuer_acmca_arns" { 379 | description = "List of ACM Private CA ARNs to issue certificates from" 380 | type = list(string) 381 | default = [] 382 | } 383 | 384 | # AWS VPC CNI 385 | variable "attach_aws_vpc_cni_policy" { 386 | description = "Determines whether to attach the VPC CNI IAM policy to the role" 387 | type = bool 388 | default = false 389 | } 390 | 391 | variable "aws_vpc_cni_policy_name" { 392 | description = "Custom name of the VPC CNI IAM policy" 393 | type = string 394 | default = null 395 | } 396 | 397 | variable "aws_vpc_cni_enable_cloudwatch_logs" { 398 | description = "Determines whether to enable VPC CNI permission to create CloudWatch Log groups and publish network policy events" 399 | type = bool 400 | default = false 401 | } 402 | 403 | variable "aws_vpc_cni_enable_ipv4" { 404 | description = "Determines whether to enable IPv4 permissions for VPC CNI policy" 405 | type = bool 406 | default = false 407 | } 408 | 409 | variable "aws_vpc_cni_enable_ipv6" { 410 | description = "Determines whether to enable IPv6 permissions for VPC CNI policy" 411 | type = bool 412 | default = false 413 | } 414 | 415 | # Cert Manager 416 | variable "attach_cert_manager_policy" { 417 | description = "Determines whether to attach the Cert Manager IAM policy to the role" 418 | type = bool 419 | default = false 420 | } 421 | 422 | variable "cert_manager_policy_name" { 423 | description = "Custom name of the Cert Manager IAM policy" 424 | type = string 425 | default = null 426 | } 427 | 428 | variable "cert_manager_hosted_zone_arns" { 429 | description = "Route53 hosted zone ARNs to allow Cert manager to manage records" 430 | type = list(string) 431 | default = [] 432 | } 433 | 434 | # Cluster autoscaler 435 | variable "attach_cluster_autoscaler_policy" { 436 | description = "Determines whether to attach the Cluster Autoscaler IAM policy to the role" 437 | type = bool 438 | default = false 439 | } 440 | 441 | variable "cluster_autoscaler_policy_name" { 442 | description = "Custom name of the Cluster Autoscaler IAM policy" 443 | type = string 444 | default = null 445 | } 446 | 447 | variable "cluster_autoscaler_cluster_names" { 448 | description = "List of cluster names to appropriately scope permissions within the Cluster Autoscaler IAM policy" 449 | type = list(string) 450 | default = [] 451 | } 452 | 453 | # External DNS 454 | variable "attach_external_dns_policy" { 455 | description = "Determines whether to attach the External DNS IAM policy to the role" 456 | type = bool 457 | default = false 458 | } 459 | 460 | variable "external_dns_policy_name" { 461 | description = "Custom name of the External DNS IAM policy" 462 | type = string 463 | default = null 464 | } 465 | 466 | variable "external_dns_hosted_zone_arns" { 467 | description = "Route53 hosted zone ARNs to allow External DNS to manage records" 468 | type = list(string) 469 | default = [] 470 | } 471 | 472 | # External Secrets 473 | variable "attach_external_secrets_policy" { 474 | description = "Determines whether to attach the External Secrets policy to the role" 475 | type = bool 476 | default = false 477 | } 478 | 479 | variable "external_secrets_policy_name" { 480 | description = "Custom name of the External Secrets IAM policy" 481 | type = string 482 | default = null 483 | } 484 | 485 | variable "external_secrets_ssm_parameter_arns" { 486 | description = "List of Systems Manager Parameter ARNs that contain secrets to mount using External Secrets" 487 | type = list(string) 488 | default = [] 489 | } 490 | 491 | variable "external_secrets_secrets_manager_arns" { 492 | description = "List of Secrets Manager ARNs that contain secrets to mount using External Secrets" 493 | type = list(string) 494 | default = [] 495 | } 496 | 497 | variable "external_secrets_kms_key_arns" { 498 | description = "List of KMS Key ARNs that are used by Secrets Manager that contain secrets to mount using External Secrets" 499 | type = list(string) 500 | default = [] 501 | } 502 | 503 | variable "external_secrets_create_permission" { 504 | description = "Determines whether External Secrets has permission to create/delete secrets" 505 | type = bool 506 | default = false 507 | } 508 | 509 | # Mountpoint S3 CSI 510 | variable "attach_mountpoint_s3_csi_policy" { 511 | description = "Determines whether to attach the Mountpoint S3 CSI IAM policy to the role" 512 | type = bool 513 | default = false 514 | } 515 | 516 | variable "mountpoint_s3_csi_policy_name" { 517 | description = "Custom name of the Mountpoint S3 CSI IAM policy" 518 | type = string 519 | default = null 520 | } 521 | 522 | variable "mountpoint_s3_csi_bucket_arns" { 523 | description = "List of S3 Bucket ARNs that Mountpoint S3 CSI needs access to list" 524 | type = list(string) 525 | default = [] 526 | } 527 | 528 | variable "mountpoint_s3_csi_bucket_path_arns" { 529 | description = "S3 path ARNs to allow Mountpoint S3 CSI driver to manage items at the provided path(s). This is required if `attach_mountpoint_s3_csi_policy = true`" 530 | type = list(string) 531 | default = [] 532 | } 533 | 534 | # PGAnalyze 535 | 536 | variable "attach_pganalyze_policy" { 537 | description = "Determines whether to attach the PGAnalyze IAM policy to the role" 538 | type = bool 539 | default = false 540 | } 541 | 542 | variable "pganalyze_policy_name" { 543 | description = "Custom name of the PGAnalyze IAM policy" 544 | type = string 545 | default = null 546 | } 547 | 548 | # Velero 549 | variable "attach_velero_policy" { 550 | description = "Determines whether to attach the Velero IAM policy to the role" 551 | type = bool 552 | default = false 553 | } 554 | 555 | variable "velero_policy_name" { 556 | description = "Custom name of the Velero IAM policy" 557 | type = string 558 | default = null 559 | } 560 | 561 | variable "velero_s3_bucket_arns" { 562 | description = "List of S3 Bucket ARNs that Velero needs access to list" 563 | type = list(string) 564 | default = [] 565 | } 566 | 567 | variable "velero_s3_bucket_path_arns" { 568 | description = "S3 path ARNs to allow Velero to manage items at the provided path(s). This is required if `attach_mountpoint_s3_csi_policy = true`" 569 | type = list(string) 570 | default = [] 571 | } 572 | 573 | variable "velero_kms_arns" { 574 | description = "KMS key ARNs to allow Velero to manage encrypted s3 buckets" 575 | type = list(string) 576 | default = [] 577 | } 578 | -------------------------------------------------------------------------------- /examples/complete/outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Custom Pod Identity 3 | ################################################################################ 4 | 5 | output "custom_pod_identity_iam_role_arn" { 6 | description = "ARN of IAM role" 7 | value = module.custom_pod_identity.iam_role_arn 8 | } 9 | 10 | output "custom_pod_identity_iam_role_name" { 11 | description = "Name of IAM role" 12 | value = module.custom_pod_identity.iam_role_name 13 | } 14 | 15 | output "custom_pod_identity_iam_role_path" { 16 | description = "Path of IAM role" 17 | value = module.custom_pod_identity.iam_role_path 18 | } 19 | 20 | output "custom_pod_identity_iam_role_unique_id" { 21 | description = "Unique ID of IAM role" 22 | value = module.custom_pod_identity.iam_role_unique_id 23 | } 24 | 25 | output "custom_pod_identity_iam_policy_arn" { 26 | description = "The ARN assigned by AWS to this policy" 27 | value = module.custom_pod_identity.iam_policy_arn 28 | } 29 | 30 | output "custom_pod_identity_iam_policy_name" { 31 | description = "Name of IAM policy" 32 | value = module.custom_pod_identity.iam_policy_name 33 | } 34 | 35 | output "custom_pod_identity_iam_policy_id" { 36 | description = "ID of IAM policy" 37 | value = module.custom_pod_identity.iam_policy_id 38 | } 39 | 40 | output "custom_pod_identity_associations" { 41 | description = "Map of Pod Identity associations created" 42 | value = module.custom_pod_identity.associations 43 | } 44 | 45 | ################################################################################ 46 | # AWS Gateway Controller 47 | ################################################################################ 48 | 49 | output "aws_gateway_controller_pod_identity_iam_role_arn" { 50 | description = "ARN of IAM role" 51 | value = module.aws_gateway_controller_pod_identity.iam_role_arn 52 | } 53 | 54 | output "aws_gateway_controller_pod_identity_iam_role_name" { 55 | description = "Name of IAM role" 56 | value = module.aws_gateway_controller_pod_identity.iam_role_name 57 | } 58 | 59 | output "aws_gateway_controller_pod_identity_iam_role_path" { 60 | description = "Path of IAM role" 61 | value = module.aws_gateway_controller_pod_identity.iam_role_path 62 | } 63 | 64 | output "aws_gateway_controller_pod_identity_iam_role_unique_id" { 65 | description = "Unique ID of IAM role" 66 | value = module.aws_gateway_controller_pod_identity.iam_role_unique_id 67 | } 68 | 69 | output "aws_gateway_controller_pod_identity_iam_policy_arn" { 70 | description = "The ARN assigned by AWS to this policy" 71 | value = module.aws_gateway_controller_pod_identity.iam_policy_arn 72 | } 73 | 74 | output "aws_gateway_controller_pod_identity_iam_policy_name" { 75 | description = "Name of IAM policy" 76 | value = module.aws_gateway_controller_pod_identity.iam_policy_name 77 | } 78 | 79 | output "aws_gateway_controller_pod_identity_iam_policy_id" { 80 | description = "ID of IAM policy" 81 | value = module.aws_gateway_controller_pod_identity.iam_policy_id 82 | } 83 | 84 | output "aws_gateway_controller_pod_identity_associations" { 85 | description = "Map of Pod Identity associations created" 86 | value = module.aws_gateway_controller_pod_identity.associations 87 | } 88 | 89 | ################################################################################ 90 | # Cert-Manager 91 | ################################################################################ 92 | 93 | output "cert_manager_pod_identity_iam_role_arn" { 94 | description = "ARN of IAM role" 95 | value = module.cert_manager_pod_identity.iam_role_arn 96 | } 97 | 98 | output "cert_manager_pod_identity_iam_role_name" { 99 | description = "Name of IAM role" 100 | value = module.cert_manager_pod_identity.iam_role_name 101 | } 102 | 103 | output "cert_manager_pod_identity_iam_role_path" { 104 | description = "Path of IAM role" 105 | value = module.cert_manager_pod_identity.iam_role_path 106 | } 107 | 108 | output "cert_manager_pod_identity_iam_role_unique_id" { 109 | description = "Unique ID of IAM role" 110 | value = module.cert_manager_pod_identity.iam_role_unique_id 111 | } 112 | 113 | output "cert_manager_pod_identity_iam_policy_arn" { 114 | description = "The ARN assigned by AWS to this policy" 115 | value = module.cert_manager_pod_identity.iam_policy_arn 116 | } 117 | 118 | output "cert_manager_pod_identity_iam_policy_name" { 119 | description = "Name of IAM policy" 120 | value = module.cert_manager_pod_identity.iam_policy_name 121 | } 122 | 123 | output "cert_manager_pod_identity_iam_policy_id" { 124 | description = "ID of IAM policy" 125 | value = module.cert_manager_pod_identity.iam_policy_id 126 | } 127 | 128 | output "cert_manager_pod_identity_associations" { 129 | description = "Map of Pod Identity associations created" 130 | value = module.cert_manager_pod_identity.associations 131 | } 132 | 133 | ################################################################################ 134 | # AWS CloudWatch Observability 135 | ################################################################################ 136 | 137 | output "aws_cloudwatch_observability_pod_identity_iam_role_arn" { 138 | description = "ARN of IAM role" 139 | value = module.aws_cloudwatch_observability_pod_identity.iam_role_arn 140 | } 141 | 142 | output "aws_cloudwatch_observability_pod_identity_iam_role_name" { 143 | description = "Name of IAM role" 144 | value = module.aws_cloudwatch_observability_pod_identity.iam_role_name 145 | } 146 | 147 | output "aws_cloudwatch_observability_pod_identity_iam_role_path" { 148 | description = "Path of IAM role" 149 | value = module.aws_cloudwatch_observability_pod_identity.iam_role_path 150 | } 151 | 152 | output "aws_cloudwatch_observability_pod_identity_iam_role_unique_id" { 153 | description = "Unique ID of IAM role" 154 | value = module.aws_cloudwatch_observability_pod_identity.iam_role_unique_id 155 | } 156 | 157 | output "aws_cloudwatch_observability_pod_identity_iam_policy_arn" { 158 | description = "The ARN assigned by AWS to this policy" 159 | value = module.aws_cloudwatch_observability_pod_identity.iam_policy_arn 160 | } 161 | 162 | output "aws_cloudwatch_observability_pod_identity_iam_policy_name" { 163 | description = "Name of IAM policy" 164 | value = module.aws_cloudwatch_observability_pod_identity.iam_policy_name 165 | } 166 | 167 | output "aws_cloudwatch_observability_pod_identity_iam_policy_id" { 168 | description = "ID of IAM policy" 169 | value = module.aws_cloudwatch_observability_pod_identity.iam_policy_id 170 | } 171 | 172 | output "aws_cloudwatch_observability_pod_identity_associations" { 173 | description = "Map of Pod Identity associations created" 174 | value = module.aws_cloudwatch_observability_pod_identity.associations 175 | } 176 | 177 | ################################################################################ 178 | # Cluster Autoscaler 179 | ################################################################################ 180 | 181 | output "cluster_autoscaler_pod_identity_iam_role_arn" { 182 | description = "ARN of IAM role" 183 | value = module.cluster_autoscaler_pod_identity.iam_role_arn 184 | } 185 | 186 | output "cluster_autoscaler_pod_identity_iam_role_name" { 187 | description = "Name of IAM role" 188 | value = module.cluster_autoscaler_pod_identity.iam_role_name 189 | } 190 | 191 | output "cluster_autoscaler_pod_identity_iam_role_path" { 192 | description = "Path of IAM role" 193 | value = module.cluster_autoscaler_pod_identity.iam_role_path 194 | } 195 | 196 | output "cluster_autoscaler_pod_identity_iam_role_unique_id" { 197 | description = "Unique ID of IAM role" 198 | value = module.cluster_autoscaler_pod_identity.iam_role_unique_id 199 | } 200 | 201 | output "cluster_autoscaler_pod_identity_iam_policy_arn" { 202 | description = "The ARN assigned by AWS to this policy" 203 | value = module.cluster_autoscaler_pod_identity.iam_policy_arn 204 | } 205 | 206 | output "cluster_autoscaler_pod_identity_iam_policy_name" { 207 | description = "Name of IAM policy" 208 | value = module.cluster_autoscaler_pod_identity.iam_policy_name 209 | } 210 | 211 | output "cluster_autoscaler_pod_identity_iam_policy_id" { 212 | description = "ID of IAM policy" 213 | value = module.cluster_autoscaler_pod_identity.iam_policy_id 214 | } 215 | 216 | output "cluster_autoscaler_pod_identity_associations" { 217 | description = "Map of Pod Identity associations created" 218 | value = module.cluster_autoscaler_pod_identity.associations 219 | } 220 | 221 | ################################################################################ 222 | # AWS EBS CSI Driver 223 | ################################################################################ 224 | 225 | output "aws_ebs_csi_pod_identity_iam_role_arn" { 226 | description = "ARN of IAM role" 227 | value = module.aws_ebs_csi_pod_identity.iam_role_arn 228 | } 229 | 230 | output "aws_ebs_csi_pod_identity_iam_role_name" { 231 | description = "Name of IAM role" 232 | value = module.aws_ebs_csi_pod_identity.iam_role_name 233 | } 234 | 235 | output "aws_ebs_csi_pod_identity_iam_role_path" { 236 | description = "Path of IAM role" 237 | value = module.aws_ebs_csi_pod_identity.iam_role_path 238 | } 239 | 240 | output "aws_ebs_csi_pod_identity_iam_role_unique_id" { 241 | description = "Unique ID of IAM role" 242 | value = module.aws_ebs_csi_pod_identity.iam_role_unique_id 243 | } 244 | 245 | output "aws_ebs_csi_pod_identity_iam_policy_arn" { 246 | description = "The ARN assigned by AWS to this policy" 247 | value = module.aws_ebs_csi_pod_identity.iam_policy_arn 248 | } 249 | 250 | output "aws_ebs_csi_pod_identity_iam_policy_name" { 251 | description = "Name of IAM policy" 252 | value = module.aws_ebs_csi_pod_identity.iam_policy_name 253 | } 254 | 255 | output "aws_ebs_csi_pod_identity_iam_policy_id" { 256 | description = "ID of IAM policy" 257 | value = module.aws_ebs_csi_pod_identity.iam_policy_id 258 | } 259 | 260 | output "aws_ebs_csi_pod_identity_associations" { 261 | description = "Map of Pod Identity associations created" 262 | value = module.aws_ebs_csi_pod_identity.associations 263 | } 264 | 265 | ################################################################################ 266 | # AWS EFS CSI Driver 267 | ################################################################################ 268 | 269 | output "aws_efs_csi_pod_identity_iam_role_arn" { 270 | description = "ARN of IAM role" 271 | value = module.aws_efs_csi_pod_identity.iam_role_arn 272 | } 273 | 274 | output "aws_efs_csi_pod_identity_iam_role_name" { 275 | description = "Name of IAM role" 276 | value = module.aws_efs_csi_pod_identity.iam_role_name 277 | } 278 | 279 | output "aws_efs_csi_pod_identity_iam_role_path" { 280 | description = "Path of IAM role" 281 | value = module.aws_efs_csi_pod_identity.iam_role_path 282 | } 283 | 284 | output "aws_efs_csi_pod_identity_iam_role_unique_id" { 285 | description = "Unique ID of IAM role" 286 | value = module.aws_efs_csi_pod_identity.iam_role_unique_id 287 | } 288 | 289 | output "aws_efs_csi_pod_identity_iam_policy_arn" { 290 | description = "The ARN assigned by AWS to this policy" 291 | value = module.aws_efs_csi_pod_identity.iam_policy_arn 292 | } 293 | 294 | output "aws_efs_csi_pod_identity_iam_policy_name" { 295 | description = "Name of IAM policy" 296 | value = module.aws_efs_csi_pod_identity.iam_policy_name 297 | } 298 | 299 | output "aws_efs_csi_pod_identity_iam_policy_id" { 300 | description = "ID of IAM policy" 301 | value = module.aws_efs_csi_pod_identity.iam_policy_id 302 | } 303 | 304 | output "aws_efs_csi_pod_identity_associations" { 305 | description = "Map of Pod Identity associations created" 306 | value = module.aws_efs_csi_pod_identity.associations 307 | } 308 | 309 | ################################################################################ 310 | # External-DNS 311 | ################################################################################ 312 | 313 | output "external_dns_pod_identity_iam_role_arn" { 314 | description = "ARN of IAM role" 315 | value = module.external_dns_pod_identity.iam_role_arn 316 | } 317 | 318 | output "external_dns_pod_identity_iam_role_name" { 319 | description = "Name of IAM role" 320 | value = module.external_dns_pod_identity.iam_role_name 321 | } 322 | 323 | output "external_dns_pod_identity_iam_role_path" { 324 | description = "Path of IAM role" 325 | value = module.external_dns_pod_identity.iam_role_path 326 | } 327 | 328 | output "external_dns_pod_identity_iam_role_unique_id" { 329 | description = "Unique ID of IAM role" 330 | value = module.external_dns_pod_identity.iam_role_unique_id 331 | } 332 | 333 | output "external_dns_pod_identity_iam_policy_arn" { 334 | description = "The ARN assigned by AWS to this policy" 335 | value = module.external_dns_pod_identity.iam_policy_arn 336 | } 337 | 338 | output "external_dns_pod_identity_iam_policy_name" { 339 | description = "Name of IAM policy" 340 | value = module.external_dns_pod_identity.iam_policy_name 341 | } 342 | 343 | output "external_dns_pod_identity_iam_policy_id" { 344 | description = "ID of IAM policy" 345 | value = module.external_dns_pod_identity.iam_policy_id 346 | } 347 | 348 | output "external_dns_pod_identity_associations" { 349 | description = "Map of Pod Identity associations created" 350 | value = module.external_dns_pod_identity.associations 351 | } 352 | 353 | ################################################################################ 354 | # External Secrets 355 | ################################################################################ 356 | 357 | output "external_secrets_pod_identity_iam_role_arn" { 358 | description = "ARN of IAM role" 359 | value = module.external_secrets_pod_identity.iam_role_arn 360 | } 361 | 362 | output "external_secrets_pod_identity_iam_role_name" { 363 | description = "Name of IAM role" 364 | value = module.external_secrets_pod_identity.iam_role_name 365 | } 366 | 367 | output "external_secrets_pod_identity_iam_role_path" { 368 | description = "Path of IAM role" 369 | value = module.external_secrets_pod_identity.iam_role_path 370 | } 371 | 372 | output "external_secrets_pod_identity_iam_role_unique_id" { 373 | description = "Unique ID of IAM role" 374 | value = module.external_secrets_pod_identity.iam_role_unique_id 375 | } 376 | 377 | output "external_secrets_pod_identity_iam_policy_arn" { 378 | description = "The ARN assigned by AWS to this policy" 379 | value = module.external_secrets_pod_identity.iam_policy_arn 380 | } 381 | 382 | output "external_secrets_pod_identity_iam_policy_name" { 383 | description = "Name of IAM policy" 384 | value = module.external_secrets_pod_identity.iam_policy_name 385 | } 386 | 387 | output "external_secrets_pod_identity_iam_policy_id" { 388 | description = "ID of IAM policy" 389 | value = module.external_secrets_pod_identity.iam_policy_id 390 | } 391 | 392 | output "external_secrets_pod_identity_associations" { 393 | description = "Map of Pod Identity associations created" 394 | value = module.external_secrets_pod_identity.associations 395 | } 396 | 397 | ################################################################################ 398 | # AWS FSx for Lustre CSI Driver 399 | ################################################################################ 400 | 401 | output "aws_fsx_lustre_csi_pod_identity_iam_role_arn" { 402 | description = "ARN of IAM role" 403 | value = module.aws_fsx_lustre_csi_pod_identity.iam_role_arn 404 | } 405 | 406 | output "aws_fsx_lustre_csi_pod_identity_iam_role_name" { 407 | description = "Name of IAM role" 408 | value = module.aws_fsx_lustre_csi_pod_identity.iam_role_name 409 | } 410 | 411 | output "aws_fsx_lustre_csi_pod_identity_iam_role_path" { 412 | description = "Path of IAM role" 413 | value = module.aws_fsx_lustre_csi_pod_identity.iam_role_path 414 | } 415 | 416 | output "aws_fsx_lustre_csi_pod_identity_iam_role_unique_id" { 417 | description = "Unique ID of IAM role" 418 | value = module.aws_fsx_lustre_csi_pod_identity.iam_role_unique_id 419 | } 420 | 421 | output "aws_fsx_lustre_csi_pod_identity_iam_policy_arn" { 422 | description = "The ARN assigned by AWS to this policy" 423 | value = module.aws_fsx_lustre_csi_pod_identity.iam_policy_arn 424 | } 425 | 426 | output "aws_fsx_lustre_csi_pod_identity_iam_policy_name" { 427 | description = "Name of IAM policy" 428 | value = module.aws_fsx_lustre_csi_pod_identity.iam_policy_name 429 | } 430 | 431 | output "aws_fsx_lustre_csi_pod_identity_iam_policy_id" { 432 | description = "ID of IAM policy" 433 | value = module.aws_fsx_lustre_csi_pod_identity.iam_policy_id 434 | } 435 | 436 | output "aws_fsx_lustre_csi_pod_identity_associations" { 437 | description = "Map of Pod Identity associations created" 438 | value = module.aws_fsx_lustre_csi_pod_identity.associations 439 | } 440 | 441 | ################################################################################ 442 | # AWS Load Balancer Controller 443 | ################################################################################ 444 | 445 | output "aws_lb_controller_pod_identity_iam_role_arn" { 446 | description = "ARN of IAM role" 447 | value = module.aws_lb_controller_pod_identity.iam_role_arn 448 | } 449 | 450 | output "aws_lb_controller_pod_identity_iam_role_name" { 451 | description = "Name of IAM role" 452 | value = module.aws_lb_controller_pod_identity.iam_role_name 453 | } 454 | 455 | output "aws_lb_controller_pod_identity_iam_role_path" { 456 | description = "Path of IAM role" 457 | value = module.aws_lb_controller_pod_identity.iam_role_path 458 | } 459 | 460 | output "aws_lb_controller_pod_identity_iam_role_unique_id" { 461 | description = "Unique ID of IAM role" 462 | value = module.aws_lb_controller_pod_identity.iam_role_unique_id 463 | } 464 | 465 | output "aws_lb_controller_pod_identity_iam_policy_arn" { 466 | description = "The ARN assigned by AWS to this policy" 467 | value = module.aws_lb_controller_pod_identity.iam_policy_arn 468 | } 469 | 470 | output "aws_lb_controller_pod_identity_iam_policy_name" { 471 | description = "Name of IAM policy" 472 | value = module.aws_lb_controller_pod_identity.iam_policy_name 473 | } 474 | 475 | output "aws_lb_controller_pod_identity_iam_policy_id" { 476 | description = "ID of IAM policy" 477 | value = module.aws_lb_controller_pod_identity.iam_policy_id 478 | } 479 | 480 | output "aws_lb_controller_pod_identity_associations" { 481 | description = "Map of Pod Identity associations created" 482 | value = module.aws_lb_controller_pod_identity.associations 483 | } 484 | 485 | ################################################################################ 486 | # AWS Load Balancer Controller TargetGroup Binding Only 487 | ################################################################################ 488 | 489 | output "aws_lb_controller_targetgroup_binding_only_pod_identity_iam_role_arn" { 490 | description = "ARN of IAM role" 491 | value = module.aws_lb_controller_targetgroup_binding_only_pod_identity.iam_role_arn 492 | } 493 | 494 | output "aws_lb_controller_targetgroup_binding_only_pod_identity_iam_role_name" { 495 | description = "Name of IAM role" 496 | value = module.aws_lb_controller_targetgroup_binding_only_pod_identity.iam_role_name 497 | } 498 | 499 | output "aws_lb_controller_targetgroup_binding_only_pod_identity_iam_role_path" { 500 | description = "Path of IAM role" 501 | value = module.aws_lb_controller_targetgroup_binding_only_pod_identity.iam_role_path 502 | } 503 | 504 | output "aws_lb_controller_targetgroup_binding_only_pod_identity_iam_role_unique_id" { 505 | description = "Unique ID of IAM role" 506 | value = module.aws_lb_controller_targetgroup_binding_only_pod_identity.iam_role_unique_id 507 | } 508 | 509 | output "aws_lb_controller_targetgroup_binding_only_pod_identity_iam_policy_arn" { 510 | description = "The ARN assigned by AWS to this policy" 511 | value = module.aws_lb_controller_targetgroup_binding_only_pod_identity.iam_policy_arn 512 | } 513 | 514 | output "aws_lb_controller_targetgroup_binding_only_pod_identity_iam_policy_name" { 515 | description = "Name of IAM policy" 516 | value = module.aws_lb_controller_targetgroup_binding_only_pod_identity.iam_policy_name 517 | } 518 | 519 | output "aws_lb_controller_targetgroup_binding_only_pod_identity_iam_policy_id" { 520 | description = "ID of IAM policy" 521 | value = module.aws_lb_controller_targetgroup_binding_only_pod_identity.iam_policy_id 522 | } 523 | 524 | output "aws_lb_controller_targetgroup_binding_only_pod_identity_associations" { 525 | description = "Map of Pod Identity associations created" 526 | value = module.aws_lb_controller_targetgroup_binding_only_pod_identity.associations 527 | } 528 | 529 | ################################################################################ 530 | # AWS AppMesh Controller 531 | ################################################################################ 532 | 533 | output "aws_appmesh_controller_pod_identity_iam_role_arn" { 534 | description = "ARN of IAM role" 535 | value = module.aws_appmesh_controller_pod_identity.iam_role_arn 536 | } 537 | 538 | output "aws_appmesh_controller_pod_identity_iam_role_name" { 539 | description = "Name of IAM role" 540 | value = module.aws_appmesh_controller_pod_identity.iam_role_name 541 | } 542 | 543 | output "aws_appmesh_controller_pod_identity_iam_role_path" { 544 | description = "Path of IAM role" 545 | value = module.aws_appmesh_controller_pod_identity.iam_role_path 546 | } 547 | 548 | output "aws_appmesh_controller_pod_identity_iam_role_unique_id" { 549 | description = "Unique ID of IAM role" 550 | value = module.aws_appmesh_controller_pod_identity.iam_role_unique_id 551 | } 552 | 553 | output "aws_appmesh_controller_pod_identity_iam_policy_arn" { 554 | description = "The ARN assigned by AWS to this policy" 555 | value = module.aws_appmesh_controller_pod_identity.iam_policy_arn 556 | } 557 | 558 | output "aws_appmesh_controller_pod_identity_iam_policy_name" { 559 | description = "Name of IAM policy" 560 | value = module.aws_appmesh_controller_pod_identity.iam_policy_name 561 | } 562 | 563 | output "aws_appmesh_controller_pod_identity_iam_policy_id" { 564 | description = "ID of IAM policy" 565 | value = module.aws_appmesh_controller_pod_identity.iam_policy_id 566 | } 567 | 568 | output "aws_appmesh_controller_pod_identity_associations" { 569 | description = "Map of Pod Identity associations created" 570 | value = module.aws_appmesh_controller_pod_identity.associations 571 | } 572 | 573 | ################################################################################ 574 | # AWS AppMesh Envoy Proxy 575 | ################################################################################ 576 | 577 | output "aws_appmesh_envoy_proxy_pod_identity_iam_role_arn" { 578 | description = "ARN of IAM role" 579 | value = module.aws_appmesh_envoy_proxy_pod_identity.iam_role_arn 580 | } 581 | 582 | output "aws_appmesh_envoy_proxy_pod_identity_iam_role_name" { 583 | description = "Name of IAM role" 584 | value = module.aws_appmesh_envoy_proxy_pod_identity.iam_role_name 585 | } 586 | 587 | output "aws_appmesh_envoy_proxy_pod_identity_iam_role_path" { 588 | description = "Path of IAM role" 589 | value = module.aws_appmesh_envoy_proxy_pod_identity.iam_role_path 590 | } 591 | 592 | output "aws_appmesh_envoy_proxy_pod_identity_iam_role_unique_id" { 593 | description = "Unique ID of IAM role" 594 | value = module.aws_appmesh_envoy_proxy_pod_identity.iam_role_unique_id 595 | } 596 | 597 | output "aws_appmesh_envoy_proxy_pod_identity_iam_policy_arn" { 598 | description = "The ARN assigned by AWS to this policy" 599 | value = module.aws_appmesh_envoy_proxy_pod_identity.iam_policy_arn 600 | } 601 | 602 | output "aws_appmesh_envoy_proxy_pod_identity_iam_policy_name" { 603 | description = "Name of IAM policy" 604 | value = module.aws_appmesh_envoy_proxy_pod_identity.iam_policy_name 605 | } 606 | 607 | output "aws_appmesh_envoy_proxy_pod_identity_iam_policy_id" { 608 | description = "ID of IAM policy" 609 | value = module.aws_appmesh_envoy_proxy_pod_identity.iam_policy_id 610 | } 611 | 612 | output "aws_appmesh_envoy_proxy_pod_identity_associations" { 613 | description = "Map of Pod Identity associations created" 614 | value = module.aws_appmesh_envoy_proxy_pod_identity.associations 615 | } 616 | 617 | ################################################################################ 618 | # Amazon Managed Service for Prometheus 619 | ################################################################################ 620 | 621 | output "amazon_managed_service_prometheus_pod_identity_iam_role_arn" { 622 | description = "ARN of IAM role" 623 | value = module.amazon_managed_service_prometheus_pod_identity.iam_role_arn 624 | } 625 | 626 | output "amazon_managed_service_prometheus_pod_identity_iam_role_name" { 627 | description = "Name of IAM role" 628 | value = module.amazon_managed_service_prometheus_pod_identity.iam_role_name 629 | } 630 | 631 | output "amazon_managed_service_prometheus_pod_identity_iam_role_path" { 632 | description = "Path of IAM role" 633 | value = module.amazon_managed_service_prometheus_pod_identity.iam_role_path 634 | } 635 | 636 | output "amazon_managed_service_prometheus_pod_identity_iam_role_unique_id" { 637 | description = "Unique ID of IAM role" 638 | value = module.amazon_managed_service_prometheus_pod_identity.iam_role_unique_id 639 | } 640 | 641 | output "amazon_managed_service_prometheus_pod_identity_iam_policy_arn" { 642 | description = "The ARN assigned by AWS to this policy" 643 | value = module.amazon_managed_service_prometheus_pod_identity.iam_policy_arn 644 | } 645 | 646 | output "amazon_managed_service_prometheus_pod_identity_iam_policy_name" { 647 | description = "Name of IAM policy" 648 | value = module.amazon_managed_service_prometheus_pod_identity.iam_policy_name 649 | } 650 | 651 | output "amazon_managed_service_prometheus_pod_identity_iam_policy_id" { 652 | description = "ID of IAM policy" 653 | value = module.amazon_managed_service_prometheus_pod_identity.iam_policy_id 654 | } 655 | 656 | output "amazon_managed_service_prometheus_pod_identity_associations" { 657 | description = "Map of Pod Identity associations created" 658 | value = module.amazon_managed_service_prometheus_pod_identity.associations 659 | } 660 | 661 | ################################################################################ 662 | # Mountpoint S3 CSI Driver 663 | ################################################################################ 664 | 665 | output "mountpoint_s3_csi_pod_identity_iam_role_arn" { 666 | description = "ARN of IAM role" 667 | value = module.mountpoint_s3_csi_pod_identity.iam_role_arn 668 | } 669 | 670 | output "mountpoint_s3_csi_pod_identity_iam_role_name" { 671 | description = "Name of IAM role" 672 | value = module.mountpoint_s3_csi_pod_identity.iam_role_name 673 | } 674 | 675 | output "mountpoint_s3_csi_pod_identity_iam_role_path" { 676 | description = "Path of IAM role" 677 | value = module.mountpoint_s3_csi_pod_identity.iam_role_path 678 | } 679 | 680 | output "mountpoint_s3_csi_pod_identity_iam_role_unique_id" { 681 | description = "Unique ID of IAM role" 682 | value = module.mountpoint_s3_csi_pod_identity.iam_role_unique_id 683 | } 684 | 685 | output "mountpoint_s3_csi_pod_identity_iam_policy_arn" { 686 | description = "The ARN assigned by AWS to this policy" 687 | value = module.mountpoint_s3_csi_pod_identity.iam_policy_arn 688 | } 689 | 690 | output "mountpoint_s3_csi_pod_identity_iam_policy_name" { 691 | description = "Name of IAM policy" 692 | value = module.mountpoint_s3_csi_pod_identity.iam_policy_name 693 | } 694 | 695 | output "mountpoint_s3_csi_pod_identity_iam_policy_id" { 696 | description = "ID of IAM policy" 697 | value = module.mountpoint_s3_csi_pod_identity.iam_policy_id 698 | } 699 | 700 | output "mountpoint_s3_csi_pod_identity_associations" { 701 | description = "Map of Pod Identity associations created" 702 | value = module.mountpoint_s3_csi_pod_identity.associations 703 | } 704 | 705 | ################################################################################ 706 | # AWS Node Termination Handler 707 | ################################################################################ 708 | 709 | output "aws_node_termination_handler_pod_identity_iam_role_arn" { 710 | description = "ARN of IAM role" 711 | value = module.aws_node_termination_handler_pod_identity.iam_role_arn 712 | } 713 | 714 | output "aws_node_termination_handler_pod_identity_iam_role_name" { 715 | description = "Name of IAM role" 716 | value = module.aws_node_termination_handler_pod_identity.iam_role_name 717 | } 718 | 719 | output "aws_node_termination_handler_pod_identity_iam_role_path" { 720 | description = "Path of IAM role" 721 | value = module.aws_node_termination_handler_pod_identity.iam_role_path 722 | } 723 | 724 | output "aws_node_termination_handler_pod_identity_iam_role_unique_id" { 725 | description = "Unique ID of IAM role" 726 | value = module.aws_node_termination_handler_pod_identity.iam_role_unique_id 727 | } 728 | 729 | output "aws_node_termination_handler_pod_identity_iam_policy_arn" { 730 | description = "The ARN assigned by AWS to this policy" 731 | value = module.aws_node_termination_handler_pod_identity.iam_policy_arn 732 | } 733 | 734 | output "aws_node_termination_handler_pod_identity_iam_policy_name" { 735 | description = "Name of IAM policy" 736 | value = module.aws_node_termination_handler_pod_identity.iam_policy_name 737 | } 738 | 739 | output "aws_node_termination_handler_pod_identity_iam_policy_id" { 740 | description = "ID of IAM policy" 741 | value = module.aws_node_termination_handler_pod_identity.iam_policy_id 742 | } 743 | 744 | output "aws_node_termination_handler_pod_identity_associations" { 745 | description = "Map of Pod Identity associations created" 746 | value = module.aws_node_termination_handler_pod_identity.associations 747 | } 748 | 749 | ################################################################################ 750 | # AWS Private CA Issuer 751 | ################################################################################ 752 | 753 | output "aws_privateca_issuer_pod_identity_iam_role_arn" { 754 | description = "ARN of IAM role" 755 | value = module.aws_privateca_issuer_pod_identity.iam_role_arn 756 | } 757 | 758 | output "aws_privateca_issuer_pod_identity_iam_role_name" { 759 | description = "Name of IAM role" 760 | value = module.aws_privateca_issuer_pod_identity.iam_role_name 761 | } 762 | 763 | output "aws_privateca_issuer_pod_identity_iam_role_path" { 764 | description = "Path of IAM role" 765 | value = module.aws_privateca_issuer_pod_identity.iam_role_path 766 | } 767 | 768 | output "aws_privateca_issuer_pod_identity_iam_role_unique_id" { 769 | description = "Unique ID of IAM role" 770 | value = module.aws_privateca_issuer_pod_identity.iam_role_unique_id 771 | } 772 | 773 | output "aws_privateca_issuer_pod_identity_iam_policy_arn" { 774 | description = "The ARN assigned by AWS to this policy" 775 | value = module.aws_privateca_issuer_pod_identity.iam_policy_arn 776 | } 777 | 778 | output "aws_privateca_issuer_pod_identity_iam_policy_name" { 779 | description = "Name of IAM policy" 780 | value = module.aws_privateca_issuer_pod_identity.iam_policy_name 781 | } 782 | 783 | output "aws_privateca_issuer_pod_identity_iam_policy_id" { 784 | description = "ID of IAM policy" 785 | value = module.aws_privateca_issuer_pod_identity.iam_policy_id 786 | } 787 | 788 | output "aws_privateca_issuer_pod_identity_associations" { 789 | description = "Map of Pod Identity associations created" 790 | value = module.aws_privateca_issuer_pod_identity.associations 791 | } 792 | 793 | ################################################################################ 794 | # Velero 795 | ################################################################################ 796 | 797 | output "velero_pod_identity_iam_role_arn" { 798 | description = "ARN of IAM role" 799 | value = module.velero_pod_identity.iam_role_arn 800 | } 801 | 802 | output "velero_pod_identity_iam_role_name" { 803 | description = "Name of IAM role" 804 | value = module.velero_pod_identity.iam_role_name 805 | } 806 | 807 | output "velero_pod_identity_iam_role_path" { 808 | description = "Path of IAM role" 809 | value = module.velero_pod_identity.iam_role_path 810 | } 811 | 812 | output "velero_pod_identity_iam_role_unique_id" { 813 | description = "Unique ID of IAM role" 814 | value = module.velero_pod_identity.iam_role_unique_id 815 | } 816 | 817 | output "velero_pod_identity_iam_policy_arn" { 818 | description = "The ARN assigned by AWS to this policy" 819 | value = module.velero_pod_identity.iam_policy_arn 820 | } 821 | 822 | output "velero_pod_identity_iam_policy_name" { 823 | description = "Name of IAM policy" 824 | value = module.velero_pod_identity.iam_policy_name 825 | } 826 | 827 | output "velero_pod_identity_iam_policy_id" { 828 | description = "ID of IAM policy" 829 | value = module.velero_pod_identity.iam_policy_id 830 | } 831 | 832 | output "velero_pod_identity_associations" { 833 | description = "Map of Pod Identity associations created" 834 | value = module.velero_pod_identity.associations 835 | } 836 | 837 | ################################################################################ 838 | # AWS VPC CNI IPv4 839 | ################################################################################ 840 | 841 | output "aws_vpc_cni_ipv4_pod_identity_iam_role_arn" { 842 | description = "ARN of IAM role" 843 | value = module.aws_vpc_cni_ipv4_pod_identity.iam_role_arn 844 | } 845 | 846 | output "aws_vpc_cni_ipv4_pod_identity_iam_role_name" { 847 | description = "Name of IAM role" 848 | value = module.aws_vpc_cni_ipv4_pod_identity.iam_role_name 849 | } 850 | 851 | output "aws_vpc_cni_ipv4_pod_identity_iam_role_path" { 852 | description = "Path of IAM role" 853 | value = module.aws_vpc_cni_ipv4_pod_identity.iam_role_path 854 | } 855 | 856 | output "aws_vpc_cni_ipv4_pod_identity_iam_role_unique_id" { 857 | description = "Unique ID of IAM role" 858 | value = module.aws_vpc_cni_ipv4_pod_identity.iam_role_unique_id 859 | } 860 | 861 | output "aws_vpc_cni_ipv4_pod_identity_iam_policy_arn" { 862 | description = "The ARN assigned by AWS to this policy" 863 | value = module.aws_vpc_cni_ipv4_pod_identity.iam_policy_arn 864 | } 865 | 866 | output "aws_vpc_cni_ipv4_pod_identity_iam_policy_name" { 867 | description = "Name of IAM policy" 868 | value = module.aws_vpc_cni_ipv4_pod_identity.iam_policy_name 869 | } 870 | 871 | output "aws_vpc_cni_ipv4_pod_identity_iam_policy_id" { 872 | description = "ID of IAM policy" 873 | value = module.aws_vpc_cni_ipv4_pod_identity.iam_policy_id 874 | } 875 | 876 | output "aws_vpc_cni_ipv4_pod_identity_associations" { 877 | description = "Map of Pod Identity associations created" 878 | value = module.aws_vpc_cni_ipv4_pod_identity.associations 879 | } 880 | 881 | ################################################################################ 882 | # AWS VPC CNI IPv6 883 | ################################################################################ 884 | 885 | output "aws_vpc_cni_ipv6_pod_identity_iam_role_arn" { 886 | description = "ARN of IAM role" 887 | value = module.aws_vpc_cni_ipv6_pod_identity.iam_role_arn 888 | } 889 | 890 | output "aws_vpc_cni_ipv6_pod_identity_iam_role_name" { 891 | description = "Name of IAM role" 892 | value = module.aws_vpc_cni_ipv6_pod_identity.iam_role_name 893 | } 894 | 895 | output "aws_vpc_cni_ipv6_pod_identity_iam_role_path" { 896 | description = "Path of IAM role" 897 | value = module.aws_vpc_cni_ipv6_pod_identity.iam_role_path 898 | } 899 | 900 | output "aws_vpc_cni_ipv6_pod_identity_iam_role_unique_id" { 901 | description = "Unique ID of IAM role" 902 | value = module.aws_vpc_cni_ipv6_pod_identity.iam_role_unique_id 903 | } 904 | 905 | output "aws_vpc_cni_ipv6_pod_identity_iam_policy_arn" { 906 | description = "The ARN assigned by AWS to this policy" 907 | value = module.aws_vpc_cni_ipv6_pod_identity.iam_policy_arn 908 | } 909 | 910 | output "aws_vpc_cni_ipv6_pod_identity_iam_policy_name" { 911 | description = "Name of IAM policy" 912 | value = module.aws_vpc_cni_ipv6_pod_identity.iam_policy_name 913 | } 914 | 915 | output "aws_vpc_cni_ipv6_pod_identity_iam_policy_id" { 916 | description = "ID of IAM policy" 917 | value = module.aws_vpc_cni_ipv6_pod_identity.iam_policy_id 918 | } 919 | 920 | output "aws_vpc_cni_ipv6_pod_identity_associations" { 921 | description = "Map of Pod Identity associations created" 922 | value = module.aws_vpc_cni_ipv6_pod_identity.associations 923 | } 924 | --------------------------------------------------------------------------------