1
0
mirror of https://github.com/terraform-aws-modules/terraform-aws-eks.git synced 2025-09-09 19:32:58 +08:00

feat!: Upgrade min AWS provider and Terraform versions to 6.0 and 1.5.7 respectively (#3412)

* feat!: Upgrade min AWS provider and Terraform versions to `6.0` and `1.5.7` respectively

* fix: Remove deprecated arguments in AWS v6.0 provider, upgrade Helm provider to v3.0, bump VPC module to v6.0

* fix: Remove `aws-auth` sub-module

* fix: Remove `platform` and `cluster_service_ipv4_cidr` variables from `user-data` sub-module

* fix: Resolve all marked `todos` that have been accumulated

* fix: Set default `http_put_response_hop_limit` to `1`

* fix: Remove IRSA support from Karpenter sub-module

* fix: Avoid making GET requests from data sources unless absolutely necessary

* feat: Add variable optional attribute definitions

* feat: Bump KMS key module version to latest, add remaining variable attribute definitions

* fix: Remove `cluster_` prefix from variable names to better match the underlying API

* fix: Move all EFA logic to the nodegroup itself

* fix: Remove arguments that do not make sense in EKS

* fix: Updates from plan validation

* fix: Remove more self-managed node group attributes that are commonly not used in EKS clusters

* fix: Remove data plane compute `*_defaults` variables that do not work with variable optional attributes

* fix: Ignore changes to `bootstrap_self_managed_addons` to aid in upgrade

* feat: Add support for `region` argument on relevant resources

* feat: Initial pass on upgrade guide

* fix: Updates from testing and validating EKS managed node group

* fix: Updates from testing and validating self-managed node group

* docs: Ensure addon ussage documented is aligned

* feat: Switch to dualstack OIDC issuer URL

* feat: Allow sourcing over overriding the Karpenter assume role policy

* fix: Use `Bool` instead of `StringEquals` for DenyHTTP queue policy

* fix: Correct use of `nullable` and default value propagation
This commit is contained in:
Bryant Biggs
2025-07-23 15:11:01 -05:00
committed by GitHub
parent 8a0efdbbc8
commit 416515a0da
84 changed files with 4111 additions and 3339 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.99.4
rev: v1.99.5
hooks:
- id: terraform_fmt
- id: terraform_docs
+150 -156
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -11,3 +11,4 @@
- [Upgrade to v18.x](https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/UPGRADE-18.0.md)
- [Upgrade to v19.x](https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/UPGRADE-19.0.md)
- [Upgrade to v20.x](https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/UPGRADE-20.0.md)
- [Upgrade to v21.x](https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/UPGRADE-21.0.md)
+328
View File
@@ -0,0 +1,328 @@
# Upgrade from v20.x to v21.x
If you have any questions regarding this upgrade process, please consult the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-eks/tree/master/examples) directory:
If you find a bug, please open an issue with supporting configuration to reproduce.
## List of backwards incompatible changes
- Terraform `v1.5.7` is now minimum supported version
- AWS provider `v6.0.0` is now minimum supported version
- TLS provider `v4.0.0` is now minimum supported version
- The `aws-auth` sub-module has been removed. Users who wish to utilize its functionality can continue to do so by specifying a `v20.x` version, or `~> v20.0` version constraint in their module source.
- `bootstrap_self_managed_addons` is now hardcoded to `false`. This is a legacy setting and instead users should utilize the EKS addons API, which is what this module does by default. In conjunction with this change, the `bootstrap_self_managed_addons` is now ignored by the module to aid in upgrading without disruption (otherwise it would require cluster re-creation).
- When enabling `enable_efa_support` or creating placement groups within a node group, users must now specify the correct `subnet_ids`; the module no longer tries to automatically select a suitable subnet.
- EKS managed node group:
- IMDS now default to a hop limit of 1 (previously was 2)
- `ami_type` now defaults to `AL2023_x86_64_STANDARD`
- `enable_monitoring` is now set to `false` by default
- `enable_efa_only` is now set to `true` by default
- `use_latest_ami_release_version` is now set to `true` by default
- Support for autoscaling group schedules has been removed
- Self-managed node group:
- IMDS now default to a hop limit of 1 (previously was 2)
- `ami_type` now defaults to `AL2023_x86_64_STANDARD`
- `enable_monitoring` is now set to `false` by default
- `enable_efa_only` is now set to `true` by default
- Support for autoscaling group schedules has been removed
- Karpenter:
- Native support for IAM roles for service accounts (IRSA) has been removed; EKS Pod Identity is now enabled by default
- Karpenter controller policy for prior to Karpenter `v1` have been removed (i.e. `v0.33`); the `v1` policy is now used by default
- `create_pod_identity_association` is now set to `true` by default
- `addons.resolve_conflicts_on_create` is now set to `"NONE"` by default (was `"OVERWRITE"`).
- `addons.most_recent` is now set to `true` by default (was `false`).
- `cluster_identity_providers.issuer_url` is now required to be set by users; the prior incorrect default has been removed. See https://github.com/terraform-aws-modules/terraform-aws-eks/pull/3055 and https://github.com/kubernetes/kubernetes/pull/123561 for more details.
- The OIDC issuer URL for IAM roles for service accounts (IRSA) has been changed to use the new dual stack`oidc-eks` endpoint instead of `oidc.eks`. This is to align with https://github.com/aws/containers-roadmap/issues/2038#issuecomment-2278450601
## Additional changes
### Added
- Support for `region` parameter to specify the AWS region for the resources created if different from the provider region.
- Both the EKS managed and self-managed node groups now support creating their own security groups (again). This is primarily motivated by the changes for EFA support; previously users would need to specify `enable_efa_support` both at the cluster level (to add the appropriate security group rules to the shared node security group) as well as the node group level. However, its not always desirable to have these rules across ALL node groups when they are really only required on the node group where EFA is utilized. And similarly for other use cases, users can create custom rules for a specific node group instead of apply across ALL node groups.
### Modified
- Variable definitions now contain detailed `object` types in place of the previously used any type.
- The embedded KMS key module definition has been updated to `v4.0` to support the same version requirements as well as the new `region` argument.
### Variable and output changes
1. Removed variables:
- `enable_efa_support` - users only need to set this within the node group configuration, as the module no longer manages EFA support at the cluster level.
- `enable_security_groups_for_pods` - users can instead attach the `arn:aws:iam::aws:policy/AmazonEKSVPCResourceController` policy via `iam_role_additional_policies` if using security groups for pods.
- `eks-managed-node-group` sub-module
- `cluster_service_ipv4_cidr` - users should use `cluster_service_cidr` instead (for either IPv4 or IPv6).
- `elastic_gpu_specifications`
- `elastic_inference_accelerator`
- `platform` - this is superseded by `ami_type`
- `placement_group_strategy` - set to `cluster` by the module
- `placement_group_az` - users will need to specify the correct subnet in `subnet_ids`
- `create_schedule`
- `schedules`
- `self-managed-node-group` sub-module
- `elastic_gpu_specifications`
- `elastic_inference_accelerator`
- `platform` - this is superseded by `ami_type`
- `create_schedule`
- `schedules`
- `placement_group_az` - users will need to specify the correct subnet in `subnet_ids`
- `hibernation_options` - not valid in EKS
- `min_elb_capacity` - not valid in EKS
- `wait_for_elb_capacity` - not valid in EKS
- `wait_for_capacity_timeout` - not valid in EKS
- `default_cooldown` - not valid in EKS
- `target_group_arns` - not valid in EKS
- `service_linked_role_arn` - not valid in EKS
- `warm_pool` - not valid in EKS
- `fargate-profile` sub-module
- None
- `karpenter` sub-module
- `enable_v1_permissions` - v1 permissions are now the default
- `enable_irsa`
- `irsa_oidc_provider_arn`
- `irsa_namespace_service_accounts`
- `irsa_assume_role_condition_test`
2. Renamed variables:
- Variables prefixed with `cluster_*` have been stripped of the prefix to better match the underlying API:
- `cluster_name` -> `name`
- `cluster_version` -> `kubernetes_version`
- `cluster_enabled_log_types` -> `enabled_log_types`
- `cluster_force_update_version` -> `force_update_version`
- `cluster_compute_config` -> `compute_config`
- `cluster_upgrade_policy` -> `upgrade_policy`
- `cluster_remote_network_config` -> `remote_network_config`
- `cluster_zonal_shift_config` -> `zonal_shift_config`
- `cluster_additional_security_group_ids` -> `additional_security_group_ids`
- `cluster_endpoint_private_access` -> `endpoint_private_access`
- `cluster_endpoint_public_access` -> `endpoint_public_access`
- `cluster_endpoint_public_access_cidrs` -> `endpoint_public_access_cidrs`
- `cluster_ip_family` -> `ip_family`
- `cluster_service_ipv4_cidr` -> `service_ipv4_cidr`
- `cluster_service_ipv6_cidr` -> `service_ipv6_cidr`
- `cluster_encryption_config` -> `encryption_config`
- `create_cluster_primary_security_group_tags` -> `create_primary_security_group_tags`
- `cluster_timeouts` -> `timeouts`
- `create_cluster_security_group` -> `create_security_group`
- `cluster_security_group_id` -> `security_group_id`
- `cluster_security_group_name` -> `security_group_name`
- `cluster_security_group_use_name_prefix` -> `security_group_use_name_prefix`
- `cluster_security_group_description` -> `security_group_description`
- `cluster_security_group_additional_rules` -> `security_group_additional_rules`
- `cluster_security_group_tags` -> `security_group_tags`
- `cluster_encryption_policy_use_name_prefix` -> `encryption_policy_use_name_prefix`
- `cluster_encryption_policy_name` -> `encryption_policy_name`
- `cluster_encryption_policy_description` -> `encryption_policy_description`
- `cluster_encryption_policy_path` -> `encryption_policy_path`
- `cluster_encryption_policy_tags` -> `encryption_policy_tags`
- `cluster_addons` -> `addons`
- `cluster_addons_timeouts` -> `addons_timeouts`
- `cluster_identity_providers` -> `identity_providers`
- `eks-managed-node-group` sub-module
- `cluster_version` -> `kubernetes_version`
- `self-managed-node-group` sub-module
- `cluster_version` -> `kubernetes_version`
- `delete_timeout` -> `timeouts`
- `fargate-profile` sub-module
- None
- `karpenter` sub-module
- None
3. Added variables:
- `region`
- `eks-managed-node-group` sub-module
- `region`
- `partition` - added to reduce number of `GET` requests from data sources when possible
- `account_id` - added to reduce number of `GET` requests from data sources when possible
- `create_security_group`
- `security_group_name`
- `security_group_use_name_prefix`
- `security_group_description`
- `security_group_ingress_rules`
- `security_group_egress_rules`
- `security_group_tags`
- `self-managed-node-group` sub-module
- `region`
- `partition` - added to reduce number of `GET` requests from data sources when possible
- `account_id` - added to reduce number of `GET` requests from data sources when possible
- `create_security_group`
- `security_group_name`
- `security_group_use_name_prefix`
- `security_group_description`
- `security_group_ingress_rules`
- `security_group_egress_rules`
- `security_group_tags`
- `fargate-profile` sub-module
- `region`
- `partition` - added to reduce number of `GET` requests from data sources when possible
- `account_id` - added to reduce number of `GET` requests from data sources when possible
- `karpenter` sub-module
- `region`
4. Removed outputs:
- `eks-managed-node-group` sub-module
- `platform` - this is superseded by `ami_type`
- `autoscaling_group_schedule_arns`
- `self-managed-node-group` sub-module
- `platform` - this is superseded by `ami_type`
- `autoscaling_group_schedule_arns`
- `fargate-profile` sub-module
- None
- `karpenter` sub-module
- None
5. Renamed outputs:
- `eks-managed-node-group` sub-module
- None
- `self-managed-node-group` sub-module
- None
- `fargate-profile` sub-module
- None
- `karpenter` sub-module
- None
6. Added outputs:
- `eks-managed-node-group` sub-module
- `security_group_arn`
- `security_group_id`
- `self-managed-node-group` sub-module
- `security_group_arn`
- `security_group_id`
- `fargate-profile` sub-module
- None
- `karpenter` sub-module
- None
## Upgrade Migrations
### Before 20.x Example
```hcl
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
# Truncated for brevity ...
# Renamed variables are not shown here, please refer to the full list above.
enable_efa_support = true
eks_managed_node_group_defaults = {
iam_role_additional_policies = {
AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
}
eks_managed_node_groups = {
efa = {
ami_type = "AL2023_x86_64_NVIDIA"
instance_types = ["p5e.48xlarge"]
enable_efa_support = true
enable_efa_only = true
}
}
self_managed_node_groups = {
example = {
use_mixed_instances_policy = true
mixed_instances_policy = {
instances_distribution = {
on_demand_base_capacity = 0
on_demand_percentage_above_base_capacity = 0
on_demand_allocation_strategy = "lowest-price"
spot_allocation_strategy = "price-capacity-optimized"
}
# ASG configuration
override = [
{
instance_requirements = {
cpu_manufacturers = ["intel"]
instance_generations = ["current", "previous"]
spot_max_price_percentage_over_lowest_price = 100
vcpu_count = {
min = 1
}
allowed_instance_types = ["t*", "m*"]
}
}
]
}
}
}
}
```
### After 21.x Example
```hcl
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 21.0"
# Truncated for brevity ...
# Renamed variables are not shown here, please refer to the full list above.
eks_managed_node_groups = {
efa = {
ami_type = "AL2023_x86_64_NVIDIA"
instance_types = ["p5e.48xlarge"]
iam_role_additional_policies = {
AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
enable_efa_support = true
subnet_ids = element(module.vpc.private_subnets, 0)
}
}
self_managed_node_groups = {
example = {
use_mixed_instances_policy = true
mixed_instances_policy = {
instances_distribution = {
on_demand_base_capacity = 0
on_demand_percentage_above_base_capacity = 0
on_demand_allocation_strategy = "lowest-price"
spot_allocation_strategy = "price-capacity-optimized"
}
# ASG configuration
# Need to wrap in `launch_template` now
launch_template = {
override = [
{
instance_requirements = {
cpu_manufacturers = ["intel"]
instance_generations = ["current", "previous"]
spot_max_price_percentage_over_lowest_price = 100
vcpu_count = {
min = 1
}
allowed_instance_types = ["t*", "m*"]
}
}
]
}
}
}
}
}
```
### State Changes
No state changes required.
+21 -48
View File
@@ -57,21 +57,33 @@ Refer to the [EKS Managed Node Group documentation](https://docs.aws.amazon.com/
eks_managed_node_groups = {
custom_ami = {
ami_id = "ami-0caf35bc73450c396"
ami_type = "AL2023_x86_64_STANDARD"
# By default, EKS managed node groups will not append bootstrap script;
# this adds it back in using the default template provided by the module
# Note: this assumes the AMI provided is an EKS optimized AMI derivative
enable_bootstrap_user_data = true
pre_bootstrap_user_data = <<-EOT
export FOO=bar
cloudinit_pre_nodeadm = [{
content = <<-EOT
---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
kubelet:
config:
shutdownGracePeriod: 30s
EOT
content_type = "application/node.eks.aws"
}]
# Because we have full control over the user data supplied, we can also run additional
# scripts/configuration changes after the bootstrap script has been run
post_bootstrap_user_data = <<-EOT
echo "you are free little kubelet!"
# This is only possible when `ami_id` is specified, indicating a custom AMI
cloudinit_post_nodeadm = [{
content = <<-EOT
echo "All done"
EOT
content_type = "text/x-shellscript; charset=\"us-ascii\""
}]
}
}
```
@@ -113,9 +125,9 @@ Refer to the [Self Managed Node Group documentation](https://docs.aws.amazon.com
1. The `self-managed-node-group` uses the latest AWS EKS Optimized AMI (Linux) for the given Kubernetes version by default:
```hcl
cluster_version = "1.33"
kubernetes_version = "1.33"
# This self managed node group will use the latest AWS EKS Optimized AMI for Kubernetes 1.27
# This self managed node group will use the latest AWS EKS Optimized AMI for Kubernetes 1.33
self_managed_node_groups = {
default = {}
}
@@ -124,7 +136,7 @@ Refer to the [Self Managed Node Group documentation](https://docs.aws.amazon.com
2. To use Bottlerocket, specify the `ami_type` as one of the respective `"BOTTLEROCKET_*" types` and supply a Bottlerocket OS AMI:
```hcl
cluster_version = "1.33"
kubernetes_version = "1.33"
self_managed_node_groups = {
bottlerocket = {
@@ -139,42 +151,3 @@ See the [`examples/self-managed-node-group/` example](https://github.com/terrafo
### Fargate Profiles
Fargate profiles are straightforward to use and therefore no further details are provided here. See the [`tests/fargate-profile/` tests](https://github.com/terraform-aws-modules/terraform-aws-eks/tree/master/tests/fargate-profile) for a working example of various configurations.
### Default Configurations
Each type of compute resource (EKS managed node group, self managed node group, or Fargate profile) provides the option for users to specify a default configuration. These default configurations can be overridden from within the compute resource's individual definition. The order of precedence for configurations (from highest to least precedence):
- Compute resource individual configuration
- Compute resource family default configuration (`eks_managed_node_group_defaults`, `self_managed_node_group_defaults`, `fargate_profile_defaults`)
- Module default configuration (see `variables.tf` and `node_groups.tf`)
For example, the following creates 4 AWS EKS Managed Node Groups:
```hcl
eks_managed_node_group_defaults = {
ami_type = "AL2_x86_64"
disk_size = 50
instance_types = ["m6i.large", "m5.large", "m5n.large", "m5zn.large"]
}
eks_managed_node_groups = {
# Uses module default configurations overridden by configuration above
default = {}
# This further overrides the instance types used
compute = {
instance_types = ["c5.large", "c6i.large", "c6d.large"]
}
# This further overrides the instance types and disk size used
persistent = {
disk_size = 1024
instance_types = ["r5.xlarge", "r6i.xlarge", "r5b.xlarge"]
}
# This overrides the OS used
bottlerocket = {
ami_type = "BOTTLEROCKET_x86_64"
}
}
```
+31 -8
View File
@@ -12,23 +12,44 @@
`disk_size`, and `remote_access` can only be set when using the EKS managed node group default launch template. This module defaults to providing a custom launch template to allow for custom security groups, tag propagation, etc. If you wish to forgo the custom launch template route, you can set `use_custom_launch_template = false` and then you can set `disk_size` and `remote_access`.
### I received an error: `expect exactly one securityGroup tagged with kubernetes.io/cluster/<NAME> ...`
### I received an error: `expect exactly one securityGroup tagged with kubernetes.io/cluster/<CLUSTER_NAME> ...`
⚠️ `<CLUSTER_NAME>` would be the name of your cluster
By default, EKS creates a cluster primary security group that is created outside of the module and the EKS service adds the tag `{ "kubernetes.io/cluster/<CLUSTER_NAME>" = "owned" }`. This on its own does not cause any conflicts for addons such as the AWS Load Balancer Controller until users decide to attach both the cluster primary security group and the shared node security group created by the module (by setting `attach_cluster_primary_security_group = true`). The issue is not with having multiple security groups in your account with this tag key:value combination, but having multiple security groups with this tag key:value combination attached to nodes in the same cluster. There are a few ways to resolve this depending on your use case/intentions:
⚠️ `<CLUSTER_NAME>` below needs to be replaced with the name of your cluster
1. If you want to use the cluster primary security group, you can disable the creation of the shared node security group with:
```hcl
create_node_security_group = false # default is true
eks_managed_node_group = {
example = {
attach_cluster_primary_security_group = true # default is false
}
}
# Or for self-managed
self_managed_node_group = {
example = {
attach_cluster_primary_security_group = true # default is false
}
}
```
2. By not attaching the cluster primary security group. The cluster primary security group has quite broad access and the module has instead provided a security group with the minimum amount of access to launch an empty EKS cluster successfully and users are encouraged to open up access when necessary to support their workload.
```hcl
attach_cluster_primary_security_group = false # this is the default for the module
eks_managed_node_group = {
example = {
attach_cluster_primary_security_group = true # default is false
}
}
# Or for self-managed
self_managed_node_group = {
example = {
attach_cluster_primary_security_group = true # default is false
}
}
```
In theory, if you are attaching the cluster primary security group, you shouldn't need to use the shared node security group created by the module. However, this is left up to users to decide for their requirements and use case.
@@ -58,6 +79,8 @@ If you require a public endpoint, setting up both (public and private) and restr
The module is configured to ignore this value. Unfortunately, Terraform does not support variables within the `lifecycle` block. The setting is ignored to allow autoscaling via controllers such as cluster autoscaler or Karpenter to work properly and without interference by Terraform. Changing the desired count must be handled outside of Terraform once the node group is created.
:info: See [this](https://github.com/bryantbiggs/eks-desired-size-hack) for a workaround to this limitation.
### How do I access compute resource attributes?
Examples of accessing the attributes of the compute resource(s) created by the root module are shown below. Note - the assumption is that your cluster module definition is named `eks` as in `module "eks" { ... }`:
@@ -90,6 +113,10 @@ aws eks describe-addon-versions --query 'addons[*].addonName'
### What configuration values are available for an add-on?
> [!NOTE]
> The available configuration values will vary between add-on versions,
> typically more configuration values will be added in later versions as functionality is enabled by EKS.
You can retrieve the configuration value schema for a given addon using the following command:
```sh
@@ -286,7 +313,3 @@ Returns (at the time of writing):
}
}
```
> [!NOTE]
> The available configuration values will vary between add-on versions,
> typically more configuration values will be added in later versions as functionality is enabled by EKS.
+1 -1
View File
@@ -27,7 +27,7 @@ See the example snippet below which adds additional security group rules to the
```hcl
...
# Extend cluster security group rules
cluster_security_group_additional_rules = {
security_group_additional_rules = {
egress_nodes_ephemeral_ports_tcp = {
description = "To node 1025-65535"
protocol = "tcp"
+17 -1
View File
@@ -10,7 +10,8 @@ Users can see the various methods of using and providing user data through the [
- AMI types of `BOTTLEROCKET_*`, user data must be in TOML format
- AMI types of `WINDOWS_*`, user data must be in powershell/PS1 script format
- Self Managed Node Groups
- `AL2_x86_64` AMI type (default) -> the user data template (bash/shell script) provided by the module is used as the default; users are able to provide their own user data template
- `AL2_*` AMI types -> the user data template (bash/shell script) provided by the module is used as the default; users are able to provide their own user data template
- `AL2023_*` AMI types -> the user data template (MIME multipart format) provided by the module is used as the default; users are able to provide their own user data template
- `BOTTLEROCKET_*` AMI types -> the user data template (TOML file) provided by the module is used as the default; users are able to provide their own user data template
- `WINDOWS_*` AMI types -> the user data template (powershell/PS1 script) provided by the module is used as the default; users are able to provide their own user data template
@@ -24,10 +25,25 @@ When using an EKS managed node group, users have 2 primary routes for interactin
- Users can use the following variables to facilitate this process:
For `AL2_*`, `BOTTLEROCKET_*`, and `WINDOWS_*`:
```hcl
pre_bootstrap_user_data = "..."
```
For `AL2023_*`
```hcl
cloudinit_pre_nodeadm = [{
content = <<-EOT
---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
...
EOT
content_type = "application/node.eks.aws"
}]
```
2. If a custom AMI is used, then per the [AWS documentation](https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-custom-ami), users will need to supply the necessary user data to bootstrap and register nodes with the cluster when launched. There are two routes to facilitate this bootstrapping process:
- If the AMI used is a derivative of the [AWS EKS Optimized AMI ](https://github.com/awslabs/amazon-eks-ami), users can opt in to using a template provided by the module that provides the minimum necessary configuration to bootstrap the node when launched:
- Users can use the following variables to facilitate this process:
+4 -4
View File
@@ -24,14 +24,14 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -39,7 +39,7 @@ Note that this example may create resources which cost money. Run `terraform des
|------|--------|---------|
| <a name="module_disabled_eks"></a> [disabled\_eks](#module\_disabled\_eks) | ../.. | n/a |
| <a name="module_eks"></a> [eks](#module\_eks) | ../.. | n/a |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
+6 -6
View File
@@ -12,7 +12,7 @@ data "aws_availability_zones" "available" {
locals {
name = "ex-${basename(path.cwd)}"
cluster_version = "1.33"
kubernetes_version = "1.33"
region = "us-west-2"
vpc_cidr = "10.0.0.0/16"
@@ -32,13 +32,13 @@ locals {
module "eks" {
source = "../.."
cluster_name = local.name
cluster_version = local.cluster_version
cluster_endpoint_public_access = true
name = local.name
kubernetes_version = local.kubernetes_version
endpoint_public_access = true
enable_cluster_creator_admin_permissions = true
cluster_compute_config = {
compute_config = {
enabled = true
node_pools = ["general-purpose"]
}
@@ -61,7 +61,7 @@ module "disabled_eks" {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+8 -8
View File
@@ -25,9 +25,9 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_helm"></a> [helm](#requirement\_helm) | >= 2.7, < 3.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_helm"></a> [helm](#requirement\_helm) | >= 3.0 |
| <a name="requirement_http"></a> [http](#requirement\_http) | >= 3.4 |
| <a name="requirement_local"></a> [local](#requirement\_local) | >= 2.5 |
| <a name="requirement_tls"></a> [tls](#requirement\_tls) | >= 4.0 |
@@ -36,9 +36,9 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws.remote"></a> [aws.remote](#provider\_aws.remote) | >= 5.95, < 6.0.0 |
| <a name="provider_helm"></a> [helm](#provider\_helm) | >= 2.7, < 3.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
| <a name="provider_aws.remote"></a> [aws.remote](#provider\_aws.remote) | >= 6.0 |
| <a name="provider_helm"></a> [helm](#provider\_helm) | >= 3.0 |
| <a name="provider_http"></a> [http](#provider\_http) | >= 3.4 |
| <a name="provider_local"></a> [local](#provider\_local) | >= 2.5 |
@@ -49,8 +49,8 @@ Note that this example may create resources which cost money. Run `terraform des
| <a name="module_eks"></a> [eks](#module\_eks) | ../.. | n/a |
| <a name="module_eks_hybrid_node_role"></a> [eks\_hybrid\_node\_role](#module\_eks\_hybrid\_node\_role) | ../../modules/hybrid-node-role | n/a |
| <a name="module_key_pair"></a> [key\_pair](#module\_key\_pair) | terraform-aws-modules/key-pair/aws | ~> 2.0 |
| <a name="module_remote_node_vpc"></a> [remote\_node\_vpc](#module\_remote\_node\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
| <a name="module_remote_node_vpc"></a> [remote\_node\_vpc](#module\_remote\_node\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
+11 -11
View File
@@ -3,11 +3,11 @@ provider "aws" {
}
provider "helm" {
kubernetes {
kubernetes = {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
exec = {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
@@ -20,7 +20,7 @@ locals {
name = "ex-${basename(path.cwd)}"
region = "us-west-2"
cluster_version = "1.33"
kubernetes_version = "1.33"
tags = {
Test = local.name
@@ -36,20 +36,20 @@ locals {
module "eks" {
source = "../.."
cluster_name = local.name
cluster_version = local.cluster_version
name = local.name
kubernetes_version = local.kubernetes_version
cluster_endpoint_public_access = true
endpoint_public_access = true
enable_cluster_creator_admin_permissions = true
cluster_addons = {
addons = {
coredns = {}
eks-pod-identity-agent = {}
kube-proxy = {}
}
create_node_security_group = false
cluster_security_group_additional_rules = {
security_group_additional_rules = {
hybrid-all = {
cidr_blocks = [local.remote_network_cidr]
description = "Allow all traffic from remote node/pod network"
@@ -60,7 +60,7 @@ module "eks" {
}
}
cluster_compute_config = {
compute_config = {
enabled = true
node_pools = ["system"]
}
@@ -75,7 +75,7 @@ module "eks" {
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
cluster_remote_network_config = {
remote_network_config = {
remote_node_networks = {
cidrs = [local.remote_node_cidr]
}
@@ -106,7 +106,7 @@ data "aws_availability_zones" "available" {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
+2 -2
View File
@@ -89,7 +89,7 @@ data "aws_ami" "hybrid_node" {
provider = aws.remote
most_recent = true
name_regex = "eks-hybrid-ubuntu-${local.cluster_version}-amd64-*"
name_regex = "eks-hybrid-ubuntu-${local.kubernetes_version}-amd64-*"
owners = ["self"]
}
@@ -253,7 +253,7 @@ data "aws_availability_zones" "remote" {
module "remote_node_vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
providers = {
aws = aws.remote
+3 -3
View File
@@ -1,14 +1,14 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
helm = {
source = "hashicorp/helm"
version = ">= 2.7, < 3.0.0"
version = ">= 3.0"
}
http = {
source = "hashicorp/http"
+12 -9
View File
@@ -1,16 +1,21 @@
module "eks_al2023" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
# source = "terraform-aws-modules/eks/aws"
# version = "~> 20.0"
source = "../.."
cluster_name = "${local.name}-al2023"
cluster_version = "1.33"
name = "${local.name}-al2023"
kubernetes_version = "1.33"
# EKS Addons
cluster_addons = {
addons = {
coredns = {}
eks-pod-identity-agent = {}
eks-pod-identity-agent = {
before_compute = true
}
kube-proxy = {}
vpc-cni = {}
vpc-cni = {
before_compute = true
}
}
vpc_id = module.vpc.vpc_id
@@ -41,8 +46,6 @@ module "eks_al2023" {
kubelet:
config:
shutdownGracePeriod: 30s
featureGates:
DisableKubeletCloudCredentialProviders: true
EOT
}
]
@@ -1,16 +1,21 @@
module "eks_bottlerocket" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
# source = "terraform-aws-modules/eks/aws"
# version = "~> 20.0"
source = "../.."
cluster_name = "${local.name}-bottlerocket"
cluster_version = "1.33"
name = "${local.name}-bottlerocket"
kubernetes_version = "1.33"
# EKS Addons
cluster_addons = {
addons = {
coredns = {}
eks-pod-identity-agent = {}
eks-pod-identity-agent = {
before_compute = true
}
kube-proxy = {}
vpc-cni = {}
vpc-cni = {
before_compute = true
}
}
vpc_id = module.vpc.vpc_id
+1 -1
View File
@@ -30,7 +30,7 @@ locals {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+7 -7
View File
@@ -93,17 +93,17 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_helm"></a> [helm](#requirement\_helm) | >= 2.7, < 3.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_helm"></a> [helm](#requirement\_helm) | >= 3.0.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws.virginia"></a> [aws.virginia](#provider\_aws.virginia) | >= 5.95, < 6.0.0 |
| <a name="provider_helm"></a> [helm](#provider\_helm) | >= 2.7, < 3.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
| <a name="provider_aws.virginia"></a> [aws.virginia](#provider\_aws.virginia) | >= 6.0 |
| <a name="provider_helm"></a> [helm](#provider\_helm) | >= 3.0.0 |
## Modules
@@ -112,7 +112,7 @@ Note that this example may create resources which cost money. Run `terraform des
| <a name="module_eks"></a> [eks](#module\_eks) | ../.. | n/a |
| <a name="module_karpenter"></a> [karpenter](#module\_karpenter) | ../../modules/karpenter | n/a |
| <a name="module_karpenter_disabled"></a> [karpenter\_disabled](#module\_karpenter\_disabled) | ../../modules/karpenter | n/a |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
+14 -11
View File
@@ -8,11 +8,11 @@ provider "aws" {
}
provider "helm" {
kubernetes {
kubernetes = {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
exec = {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
@@ -54,19 +54,23 @@ locals {
module "eks" {
source = "../.."
cluster_name = local.name
cluster_version = "1.33"
name = local.name
kubernetes_version = "1.33"
# Gives Terraform identity admin access to cluster which will
# allow deploying resources (Karpenter) into the cluster
enable_cluster_creator_admin_permissions = true
cluster_endpoint_public_access = true
endpoint_public_access = true
cluster_addons = {
addons = {
coredns = {}
eks-pod-identity-agent = {}
eks-pod-identity-agent = {
before_compute = true
}
kube-proxy = {}
vpc-cni = {}
vpc-cni = {
before_compute = true
}
}
vpc_id = module.vpc.vpc_id
@@ -107,7 +111,6 @@ module "karpenter" {
source = "../../modules/karpenter"
cluster_name = module.eks.cluster_name
enable_v1_permissions = true
# Name needs to match role name passed to the EC2NodeClass
node_iam_role_use_name_prefix = false
@@ -140,7 +143,7 @@ resource "helm_release" "karpenter" {
repository_username = data.aws_ecrpublic_authorization_token.token.user_name
repository_password = data.aws_ecrpublic_authorization_token.token.password
chart = "karpenter"
version = "1.1.1"
version = "1.6.0"
wait = false
values = [
@@ -164,7 +167,7 @@ resource "helm_release" "karpenter" {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
+3 -3
View File
@@ -1,14 +1,14 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
helm = {
source = "hashicorp/helm"
version = ">= 2.7, < 3.0.0"
version = ">= 3.0.0"
}
}
}
+12 -9
View File
@@ -1,16 +1,21 @@
module "eks_al2023" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
# source = "terraform-aws-modules/eks/aws"
# version = "~> 20.0"
source = "../.."
cluster_name = "${local.name}-al2023"
cluster_version = "1.33"
name = "${local.name}-al2023"
kubernetes_version = "1.33"
# EKS Addons
cluster_addons = {
addons = {
coredns = {}
eks-pod-identity-agent = {}
eks-pod-identity-agent = {
before_compute = true
}
kube-proxy = {}
vpc-cni = {}
vpc-cni = {
before_compute = true
}
}
vpc_id = module.vpc.vpc_id
@@ -40,8 +45,6 @@ module "eks_al2023" {
kubelet:
config:
shutdownGracePeriod: 30s
featureGates:
DisableKubeletCloudCredentialProviders: true
EOT
}
]
@@ -1,16 +1,21 @@
module "eks_bottlerocket" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
# source = "terraform-aws-modules/eks/aws"
# version = "~> 20.0"
source = "../.."
cluster_name = "${local.name}-bottlerocket"
cluster_version = "1.33"
name = "${local.name}-bottlerocket"
kubernetes_version = "1.33"
# EKS Addons
cluster_addons = {
addons = {
coredns = {}
eks-pod-identity-agent = {}
eks-pod-identity-agent = {
before_compute = true
}
kube-proxy = {}
vpc-cni = {}
vpc-cni = {
before_compute = true
}
}
vpc_id = module.vpc.vpc_id
+1 -1
View File
@@ -30,7 +30,7 @@ locals {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+171 -146
View File
@@ -18,14 +18,15 @@ data "aws_iam_session_context" "current" {
locals {
create = var.create && var.putin_khuylo
account_id = try(data.aws_caller_identity.current[0].account_id, "")
partition = try(data.aws_partition.current[0].partition, "")
cluster_role = try(aws_iam_role.this[0].arn, var.iam_role_arn)
role_arn = try(aws_iam_role.this[0].arn, var.iam_role_arn)
create_outposts_local_cluster = length(var.outpost_config) > 0
enable_cluster_encryption_config = length(var.cluster_encryption_config) > 0 && !local.create_outposts_local_cluster
create_outposts_local_cluster = var.outpost_config != null
enable_encryption_config = length(var.encryption_config) > 0 && !local.create_outposts_local_cluster
auto_mode_enabled = try(var.cluster_compute_config.enabled, false)
auto_mode_enabled = try(var.compute_config.enabled, false)
}
################################################################################
@@ -35,12 +36,14 @@ locals {
resource "aws_eks_cluster" "this" {
count = local.create ? 1 : 0
name = var.cluster_name
role_arn = local.cluster_role
version = var.cluster_version
enabled_cluster_log_types = var.cluster_enabled_log_types
bootstrap_self_managed_addons = local.auto_mode_enabled ? coalesce(var.bootstrap_self_managed_addons, false) : var.bootstrap_self_managed_addons
force_update_version = var.cluster_force_update_version
region = var.region
name = var.name
role_arn = local.role_arn
version = var.kubernetes_version
enabled_cluster_log_types = var.enabled_log_types
bootstrap_self_managed_addons = false
force_update_version = var.force_update_version
access_config {
authentication_mode = var.authentication_mode
@@ -54,21 +57,21 @@ resource "aws_eks_cluster" "this" {
}
dynamic "compute_config" {
for_each = length(var.cluster_compute_config) > 0 ? [var.cluster_compute_config] : []
for_each = var.compute_config != null ? [var.compute_config] : []
content {
enabled = local.auto_mode_enabled
node_pools = local.auto_mode_enabled ? try(compute_config.value.node_pools, []) : null
node_role_arn = local.auto_mode_enabled && length(try(compute_config.value.node_pools, [])) > 0 ? try(compute_config.value.node_role_arn, aws_iam_role.eks_auto[0].arn, null) : null
enabled = compute_config.value.enabled
node_pools = compute_config.value.node_pools
node_role_arn = compute_config.value.node_pools != null ? try(compute_config.value.node_role_arn, aws_iam_role.eks_auto[0].arn, null) : null
}
}
vpc_config {
security_group_ids = compact(distinct(concat(var.cluster_additional_security_group_ids, [local.cluster_security_group_id])))
security_group_ids = compact(distinct(concat(var.additional_security_group_ids, [local.security_group_id])))
subnet_ids = coalescelist(var.control_plane_subnet_ids, var.subnet_ids)
endpoint_private_access = var.cluster_endpoint_private_access
endpoint_public_access = var.cluster_endpoint_public_access
public_access_cidrs = var.cluster_endpoint_public_access_cidrs
endpoint_private_access = var.endpoint_private_access
endpoint_public_access = var.endpoint_public_access
public_access_cidrs = var.endpoint_public_access_cidrs
}
dynamic "kubernetes_network_config" {
@@ -84,9 +87,9 @@ resource "aws_eks_cluster" "this" {
}
}
ip_family = var.cluster_ip_family
service_ipv4_cidr = var.cluster_service_ipv4_cidr
service_ipv6_cidr = var.cluster_service_ipv6_cidr
ip_family = var.ip_family
service_ipv4_cidr = var.service_ipv4_cidr
service_ipv6_cidr = var.service_ipv6_cidr
}
}
@@ -95,13 +98,22 @@ resource "aws_eks_cluster" "this" {
content {
control_plane_instance_type = outpost_config.value.control_plane_instance_type
dynamic "control_plane_placement" {
for_each = outpost_config.value.control_plane_placement != null ? [outpost_config.value.control_plane_placement] : []
content {
group_name = control_plane_placement.value.group_name
}
}
outpost_arns = outpost_config.value.outpost_arns
}
}
dynamic "encryption_config" {
# Not available on Outposts
for_each = local.enable_cluster_encryption_config ? [var.cluster_encryption_config] : []
for_each = local.enable_encryption_config ? [var.encryption_config] : []
content {
provider {
@@ -113,7 +125,7 @@ resource "aws_eks_cluster" "this" {
dynamic "remote_network_config" {
# Not valid on Outposts
for_each = length(var.cluster_remote_network_config) > 0 && !local.create_outposts_local_cluster ? [var.cluster_remote_network_config] : []
for_each = var.remote_network_config != null && !local.create_outposts_local_cluster ? [var.remote_network_config] : []
content {
dynamic "remote_node_networks" {
@@ -125,7 +137,7 @@ resource "aws_eks_cluster" "this" {
}
dynamic "remote_pod_networks" {
for_each = try([remote_network_config.value.remote_pod_networks], [])
for_each = remote_network_config.value.remote_pod_networks != null ? [remote_network_config.value.remote_pod_networks] : []
content {
cidrs = remote_pod_networks.value.cidrs
@@ -145,18 +157,18 @@ resource "aws_eks_cluster" "this" {
}
dynamic "upgrade_policy" {
for_each = length(var.cluster_upgrade_policy) > 0 ? [var.cluster_upgrade_policy] : []
for_each = var.upgrade_policy != null ? [var.upgrade_policy] : []
content {
support_type = try(upgrade_policy.value.support_type, null)
support_type = upgrade_policy.value.support_type
}
}
dynamic "zonal_shift_config" {
for_each = length(var.cluster_zonal_shift_config) > 0 ? [var.cluster_zonal_shift_config] : []
for_each = var.zonal_shift_config != null ? [var.zonal_shift_config] : []
content {
enabled = try(zonal_shift_config.value.enabled, null)
enabled = zonal_shift_config.value.enabled
}
}
@@ -166,10 +178,14 @@ resource "aws_eks_cluster" "this" {
var.cluster_tags,
)
timeouts {
create = try(var.cluster_timeouts.create, null)
update = try(var.cluster_timeouts.update, null)
delete = try(var.cluster_timeouts.delete, null)
dynamic "timeouts" {
for_each = var.timeouts != null ? [var.timeouts] : []
content {
create = var.timeouts.create
update = var.timeouts.update
delete = var.timeouts.delete
}
}
depends_on = [
@@ -182,7 +198,8 @@ resource "aws_eks_cluster" "this" {
lifecycle {
ignore_changes = [
access_config[0].bootstrap_cluster_creator_admin_permissions
access_config[0].bootstrap_cluster_creator_admin_permissions,
bootstrap_self_managed_addons,
]
}
}
@@ -192,9 +209,11 @@ resource "aws_ec2_tag" "cluster_primary_security_group" {
# Ref: https://github.com/terraform-aws-modules/terraform-aws-eks/pull/2006
# Ref: https://github.com/terraform-aws-modules/terraform-aws-eks/pull/2008
for_each = { for k, v in merge(var.tags, var.cluster_tags) :
k => v if local.create && k != "Name" && var.create_cluster_primary_security_group_tags
k => v if local.create && k != "Name" && var.create_primary_security_group_tags
}
region = var.region
resource_id = aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id
key = each.key
value = each.value
@@ -203,7 +222,9 @@ resource "aws_ec2_tag" "cluster_primary_security_group" {
resource "aws_cloudwatch_log_group" "this" {
count = local.create && var.create_cloudwatch_log_group ? 1 : 0
name = "/aws/eks/${var.cluster_name}/cluster"
region = var.region
name = "/aws/eks/${var.name}/cluster"
retention_in_days = var.cloudwatch_log_group_retention_in_days
kms_key_id = var.cloudwatch_log_group_kms_key_id
log_group_class = var.cloudwatch_log_group_class
@@ -211,7 +232,7 @@ resource "aws_cloudwatch_log_group" "this" {
tags = merge(
var.tags,
var.cloudwatch_log_group_tags,
{ Name = "/aws/eks/${var.cluster_name}/cluster" }
{ Name = "/aws/eks/${var.name}/cluster" }
)
}
@@ -222,7 +243,7 @@ resource "aws_cloudwatch_log_group" "this" {
locals {
# This replaces the one time logic from the EKS API with something that can be
# better controlled by users through Terraform
bootstrap_cluster_creator_admin_permissions = {
bootstrap_cluster_creator_admin_permissions = { for k, v in {
cluster_creator = {
principal_arn = try(data.aws_iam_session_context.current[0].issuer_arn, "")
type = "STANDARD"
@@ -236,11 +257,11 @@ locals {
}
}
}
}
} : k => v if var.enable_cluster_creator_admin_permissions }
# Merge the bootstrap behavior with the entries that users provide
merged_access_entries = merge(
{ for k, v in local.bootstrap_cluster_creator_admin_permissions : k => v if var.enable_cluster_creator_admin_permissions },
local.bootstrap_cluster_creator_admin_permissions,
var.access_entries,
)
@@ -248,7 +269,7 @@ locals {
# associations within a single entry
flattened_access_entries = flatten([
for entry_key, entry_val in local.merged_access_entries : [
for pol_key, pol_val in lookup(entry_val, "policy_associations", {}) :
for pol_key, pol_val in try(entry_val.policy_associations, {}) :
merge(
{
principal_arn = entry_val.principal_arn
@@ -258,7 +279,7 @@ locals {
{ for k, v in {
association_policy_arn = pol_val.policy_arn
association_access_scope_type = pol_val.access_scope.type
association_access_scope_namespaces = lookup(pol_val.access_scope, "namespaces", [])
association_access_scope_namespaces = try(pol_val.access_scope.namespaces, null)
} : k => v if !contains(["EC2_LINUX", "EC2_WINDOWS", "FARGATE_LINUX", "HYBRID_LINUX"], lookup(entry_val, "type", "STANDARD")) },
)
]
@@ -268,20 +289,27 @@ locals {
resource "aws_eks_access_entry" "this" {
for_each = { for k, v in local.merged_access_entries : k => v if local.create }
region = var.region
cluster_name = aws_eks_cluster.this[0].id
kubernetes_groups = try(each.value.kubernetes_groups, null)
principal_arn = each.value.principal_arn
type = try(each.value.type, "STANDARD")
type = try(each.value.type, null)
user_name = try(each.value.user_name, null)
tags = merge(var.tags, try(each.value.tags, {}))
tags = merge(
var.tags,
try(each.value.tags, {}),
)
}
resource "aws_eks_access_policy_association" "this" {
for_each = { for k, v in local.flattened_access_entries : "${v.entry_key}_${v.pol_key}" => v if local.create }
region = var.region
access_scope {
namespaces = try(each.value.association_access_scope_namespaces, [])
namespaces = each.value.association_access_scope_namespaces
type = each.value.association_access_scope_type
}
@@ -301,11 +329,13 @@ resource "aws_eks_access_policy_association" "this" {
module "kms" {
source = "terraform-aws-modules/kms/aws"
version = "2.1.0" # Note - be mindful of Terraform/provider version compatibility between modules
version = "4.0.0" # Note - be mindful of Terraform/provider version compatibility between modules
create = local.create && var.create_kms_key && local.enable_cluster_encryption_config # not valid on Outposts
create = local.create && var.create_kms_key && local.enable_encryption_config # not valid on Outposts
description = coalesce(var.kms_key_description, "${var.cluster_name} cluster encryption key")
region = var.region
description = coalesce(var.kms_key_description, "${var.name} cluster encryption key")
key_usage = "ENCRYPT_DECRYPT"
deletion_window_in_days = var.kms_key_deletion_window_in_days
enable_key_rotation = var.enable_kms_key_rotation
@@ -314,7 +344,7 @@ module "kms" {
enable_default_policy = var.kms_key_enable_default_policy
key_owners = var.kms_key_owners
key_administrators = coalescelist(var.kms_key_administrators, [try(data.aws_iam_session_context.current[0].issuer_arn, "")])
key_users = concat([local.cluster_role], var.kms_key_users)
key_users = concat([local.role_arn], var.kms_key_users)
key_service_users = var.kms_key_service_users
source_policy_documents = var.kms_key_source_policy_documents
override_policy_documents = var.kms_key_override_policy_documents
@@ -323,7 +353,7 @@ module "kms" {
aliases = var.kms_key_aliases
computed_aliases = {
# Computed since users can pass in computed values for cluster name such as random provider resources
cluster = { name = "eks/${var.cluster_name}" }
cluster = { name = "eks/${var.name}" }
}
tags = merge(
@@ -338,10 +368,10 @@ module "kms" {
################################################################################
locals {
cluster_sg_name = coalesce(var.cluster_security_group_name, "${var.cluster_name}-cluster")
create_cluster_sg = local.create && var.create_cluster_security_group
security_group_name = coalesce(var.security_group_name, "${var.name}-cluster")
create_security_group = local.create && var.create_security_group
cluster_security_group_id = local.create_cluster_sg ? aws_security_group.cluster[0].id : var.cluster_security_group_id
security_group_id = local.create_security_group ? aws_security_group.cluster[0].id : var.security_group_id
# Do not add rules to node security group if the module is not creating it
cluster_security_group_rules = { for k, v in {
@@ -357,17 +387,19 @@ locals {
}
resource "aws_security_group" "cluster" {
count = local.create_cluster_sg ? 1 : 0
count = local.create_security_group ? 1 : 0
name = var.cluster_security_group_use_name_prefix ? null : local.cluster_sg_name
name_prefix = var.cluster_security_group_use_name_prefix ? "${local.cluster_sg_name}${var.prefix_separator}" : null
description = var.cluster_security_group_description
region = var.region
name = var.security_group_use_name_prefix ? null : local.security_group_name
name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}${var.prefix_separator}" : null
description = var.security_group_description
vpc_id = var.vpc_id
tags = merge(
var.tags,
{ "Name" = local.cluster_sg_name },
var.cluster_security_group_tags
{ "Name" = local.security_group_name },
var.security_group_tags
)
lifecycle {
@@ -378,23 +410,22 @@ resource "aws_security_group" "cluster" {
resource "aws_security_group_rule" "cluster" {
for_each = { for k, v in merge(
local.cluster_security_group_rules,
var.cluster_security_group_additional_rules
) : k => v if local.create_cluster_sg }
var.security_group_additional_rules
) : k => v if local.create_security_group }
region = var.region
# Required
security_group_id = aws_security_group.cluster[0].id
protocol = each.value.protocol
from_port = each.value.from_port
to_port = each.value.to_port
type = each.value.type
# Optional
description = lookup(each.value, "description", null)
cidr_blocks = lookup(each.value, "cidr_blocks", null)
ipv6_cidr_blocks = lookup(each.value, "ipv6_cidr_blocks", null)
prefix_list_ids = lookup(each.value, "prefix_list_ids", null)
self = lookup(each.value, "self", null)
source_security_group_id = try(each.value.source_node_security_group, false) ? local.node_security_group_id : lookup(each.value, "source_security_group_id", null)
description = try(each.value.description, null)
cidr_blocks = try(each.value.cidr_blocks, null)
ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null)
prefix_list_ids = try(each.value.prefix_list_ids, null)
self = try(each.value.self, null)
source_security_group_id = try(each.value.source_node_security_group, false) ? local.node_security_group_id : try(each.value.source_security_group_id, null)
}
################################################################################
@@ -413,7 +444,7 @@ data "tls_certificate" "this" {
# Not available on outposts
count = local.create_oidc_provider && var.include_oidc_root_ca_thumbprint ? 1 : 0
url = aws_eks_cluster.this[0].identity[0].oidc[0].issuer
url = local.dualstack_oidc_issuer_url
}
resource "aws_iam_openid_connect_provider" "oidc_provider" {
@@ -422,10 +453,10 @@ resource "aws_iam_openid_connect_provider" "oidc_provider" {
client_id_list = distinct(compact(concat(["sts.amazonaws.com"], var.openid_connect_audiences)))
thumbprint_list = concat(local.oidc_root_ca_thumbprint, var.custom_oidc_thumbprints)
url = aws_eks_cluster.this[0].identity[0].oidc[0].issuer
url = local.dualstack_oidc_issuer_url
tags = merge(
{ Name = "${var.cluster_name}-eks-irsa" },
{ Name = "${var.name}-eks-irsa" },
var.tags
)
}
@@ -436,10 +467,10 @@ resource "aws_iam_openid_connect_provider" "oidc_provider" {
locals {
create_iam_role = local.create && var.create_iam_role
iam_role_name = coalesce(var.iam_role_name, "${var.cluster_name}-cluster")
iam_role_name = coalesce(var.iam_role_name, "${var.name}-cluster")
iam_role_policy_prefix = "arn:${local.partition}:iam::aws:policy"
cluster_encryption_policy_name = coalesce(var.cluster_encryption_policy_name, "${local.iam_role_name}-ClusterEncryption")
cluster_encryption_policy_name = coalesce(var.encryption_policy_name, "${local.iam_role_name}-ClusterEncryption")
# Standard EKS cluster
eks_standard_iam_role_policies = { for k, v in {
@@ -459,11 +490,6 @@ locals {
eks_outpost_iam_role_policies = { for k, v in {
AmazonEKSClusterPolicy = "${local.iam_role_policy_prefix}/AmazonEKSLocalOutpostClusterPolicy"
} : k => v if local.create_outposts_local_cluster && !local.auto_mode_enabled }
# Security groups for pods
eks_sgpp_iam_role_policies = { for k, v in {
AmazonEKSVPCResourceController = "${local.iam_role_policy_prefix}/AmazonEKSVPCResourceController"
} : k => v if var.enable_security_groups_for_pods && !local.create_outposts_local_cluster && !local.auto_mode_enabled }
}
data "aws_iam_policy_document" "assume_role_policy" {
@@ -513,7 +539,6 @@ resource "aws_iam_role_policy_attachment" "this" {
local.eks_standard_iam_role_policies,
local.eks_auto_mode_iam_role_policies,
local.eks_outpost_iam_role_policies,
local.eks_sgpp_iam_role_policies,
) : k => v if local.create_iam_role }
policy_arn = each.value
@@ -530,7 +555,7 @@ resource "aws_iam_role_policy_attachment" "additional" {
# Using separate attachment due to `The "for_each" value depends on resource attributes that cannot be determined until apply`
resource "aws_iam_role_policy_attachment" "cluster_encryption" {
# Encryption config not available on Outposts
count = local.create_iam_role && var.attach_cluster_encryption_policy && local.enable_cluster_encryption_config ? 1 : 0
count = local.create_iam_role && var.attach_encryption_policy && local.enable_encryption_config ? 1 : 0
policy_arn = aws_iam_policy.cluster_encryption[0].arn
role = aws_iam_role.this[0].name
@@ -538,12 +563,12 @@ resource "aws_iam_role_policy_attachment" "cluster_encryption" {
resource "aws_iam_policy" "cluster_encryption" {
# Encryption config not available on Outposts
count = local.create_iam_role && var.attach_cluster_encryption_policy && local.enable_cluster_encryption_config ? 1 : 0
count = local.create_iam_role && var.attach_encryption_policy && local.enable_encryption_config ? 1 : 0
name = var.cluster_encryption_policy_use_name_prefix ? null : local.cluster_encryption_policy_name
name_prefix = var.cluster_encryption_policy_use_name_prefix ? local.cluster_encryption_policy_name : null
description = var.cluster_encryption_policy_description
path = var.cluster_encryption_policy_path
name = var.encryption_policy_use_name_prefix ? null : local.cluster_encryption_policy_name
name_prefix = var.encryption_policy_use_name_prefix ? local.cluster_encryption_policy_name : null
description = var.encryption_policy_description
path = var.encryption_policy_path
policy = jsonencode({
Version = "2012-10-17"
@@ -556,12 +581,12 @@ resource "aws_iam_policy" "cluster_encryption" {
"kms:DescribeKey",
]
Effect = "Allow"
Resource = var.create_kms_key ? module.kms.key_arn : var.cluster_encryption_config.provider_key_arn
Resource = var.create_kms_key ? module.kms.key_arn : var.encryption_config.provider_key_arn
},
]
})
tags = merge(var.tags, var.cluster_encryption_policy_tags)
tags = merge(var.tags, var.encryption_policy_tags)
}
data "aws_iam_policy_document" "custom" {
@@ -722,32 +747,30 @@ resource "aws_iam_role_policy_attachment" "custom" {
# EKS Addons
################################################################################
locals {
# TODO - Set to `NONE` on next breaking change when default addons are disabled
resolve_conflicts_on_create_default = coalesce(var.bootstrap_self_managed_addons, true) ? "OVERWRITE" : "NONE"
}
data "aws_eks_addon_version" "this" {
for_each = { for k, v in var.cluster_addons : k => v if local.create && !local.create_outposts_local_cluster }
for_each = var.addons != null && local.create && !local.create_outposts_local_cluster ? var.addons : {}
addon_name = try(each.value.name, each.key)
kubernetes_version = coalesce(var.cluster_version, aws_eks_cluster.this[0].version)
# TODO - Set default fallback to `true` on next breaking change
most_recent = try(each.value.most_recent, null)
region = var.region
addon_name = coalesce(each.value.name, each.key)
kubernetes_version = coalesce(var.kubernetes_version, aws_eks_cluster.this[0].version)
most_recent = each.value.most_recent
}
resource "aws_eks_addon" "this" {
# Not supported on outposts
for_each = { for k, v in var.cluster_addons : k => v if !try(v.before_compute, false) && local.create && !local.create_outposts_local_cluster }
for_each = var.addons != null && local.create && !local.create_outposts_local_cluster ? { for k, v in var.addons : k => v if !v.before_compute } : {}
region = var.region
cluster_name = aws_eks_cluster.this[0].id
addon_name = try(each.value.name, each.key)
addon_name = coalesce(each.value.name, each.key)
addon_version = coalesce(try(each.value.addon_version, null), data.aws_eks_addon_version.this[each.key].version)
configuration_values = try(each.value.configuration_values, null)
addon_version = try(each.value.addon_version, data.aws_eks_addon_version.this[each.key].version)
configuration_values = each.value.configuration_values
dynamic "pod_identity_association" {
for_each = try(each.value.pod_identity_association, [])
for_each = each.value.pod_identity_association != null ? each.value.pod_identity_association : []
content {
role_arn = pod_identity_association.value.role_arn
@@ -755,39 +778,44 @@ resource "aws_eks_addon" "this" {
}
}
preserve = try(each.value.preserve, true)
# TODO - Set to `NONE` on next breaking change when default addons are disabled
resolve_conflicts_on_create = try(each.value.resolve_conflicts_on_create, local.resolve_conflicts_on_create_default)
resolve_conflicts_on_update = try(each.value.resolve_conflicts_on_update, "OVERWRITE")
service_account_role_arn = try(each.value.service_account_role_arn, null)
preserve = each.value.preserve
resolve_conflicts_on_create = each.value.resolve_conflicts_on_create
resolve_conflicts_on_update = each.value.resolve_conflicts_on_update
service_account_role_arn = each.value.service_account_role_arn
timeouts {
create = try(each.value.timeouts.create, var.cluster_addons_timeouts.create, null)
update = try(each.value.timeouts.update, var.cluster_addons_timeouts.update, null)
delete = try(each.value.timeouts.delete, var.cluster_addons_timeouts.delete, null)
create = try(each.value.timeouts.create, var.addons_timeouts.create, null)
update = try(each.value.timeouts.update, var.addons_timeouts.update, null)
delete = try(each.value.timeouts.delete, var.addons_timeouts.delete, null)
}
tags = merge(
var.tags,
each.value.tags,
)
# before_compute = false
depends_on = [
module.fargate_profile,
module.eks_managed_node_group,
module.self_managed_node_group,
]
tags = merge(var.tags, try(each.value.tags, {}))
}
resource "aws_eks_addon" "before_compute" {
# Not supported on outposts
for_each = { for k, v in var.cluster_addons : k => v if try(v.before_compute, false) && local.create && !local.create_outposts_local_cluster }
for_each = var.addons != null && local.create && !local.create_outposts_local_cluster ? { for k, v in var.addons : k => v if v.before_compute } : {}
region = var.region
cluster_name = aws_eks_cluster.this[0].id
addon_name = try(each.value.name, each.key)
addon_name = coalesce(each.value.name, each.key)
addon_version = coalesce(try(each.value.addon_version, null), data.aws_eks_addon_version.this[each.key].version)
configuration_values = try(each.value.configuration_values, null)
addon_version = try(each.value.addon_version, data.aws_eks_addon_version.this[each.key].version)
configuration_values = each.value.configuration_values
dynamic "pod_identity_association" {
for_each = try(each.value.pod_identity_association, [])
for_each = each.value.pod_identity_association != null ? each.value.pod_identity_association : []
content {
role_arn = pod_identity_association.value.role_arn
@@ -795,19 +823,21 @@ resource "aws_eks_addon" "before_compute" {
}
}
preserve = try(each.value.preserve, true)
# TODO - Set to `NONE` on next breaking change when default addons are disabled
resolve_conflicts_on_create = try(each.value.resolve_conflicts_on_create, local.resolve_conflicts_on_create_default)
resolve_conflicts_on_update = try(each.value.resolve_conflicts_on_update, "OVERWRITE")
service_account_role_arn = try(each.value.service_account_role_arn, null)
preserve = each.value.preserve
resolve_conflicts_on_create = each.value.resolve_conflicts_on_create
resolve_conflicts_on_update = each.value.resolve_conflicts_on_update
service_account_role_arn = each.value.service_account_role_arn
timeouts {
create = try(each.value.timeouts.create, var.cluster_addons_timeouts.create, null)
update = try(each.value.timeouts.update, var.cluster_addons_timeouts.update, null)
delete = try(each.value.timeouts.delete, var.cluster_addons_timeouts.delete, null)
create = try(each.value.timeouts.create, var.addons_timeouts.create, null)
update = try(each.value.timeouts.update, var.addons_timeouts.update, null)
delete = try(each.value.timeouts.delete, var.addons_timeouts.delete, null)
}
tags = merge(var.tags, try(each.value.tags, {}))
tags = merge(
var.tags,
each.value.tags,
)
}
################################################################################
@@ -815,33 +845,28 @@ resource "aws_eks_addon" "before_compute" {
# Note - this is different from IRSA
################################################################################
locals {
# Maintain current behavior for <= 1.29, remove default for >= 1.30
# `null` will return the latest Kubernetes version from the EKS API, which at time of writing is 1.30
# https://github.com/kubernetes/kubernetes/pull/123561
# TODO - remove on next breaking change in conjunction with issuer URL change below
idpc_backwards_compat_version = contains(["1.21", "1.22", "1.23", "1.24", "1.25", "1.26", "1.27", "1.28", "1.29"], coalesce(var.cluster_version, "1.30"))
idpc_issuer_url = local.idpc_backwards_compat_version ? try(aws_eks_cluster.this[0].identity[0].oidc[0].issuer, null) : null
}
resource "aws_eks_identity_provider_config" "this" {
for_each = { for k, v in var.cluster_identity_providers : k => v if local.create && !local.create_outposts_local_cluster }
for_each = var.identity_providers != null && local.create && !local.create_outposts_local_cluster ? var.identity_providers : {}
region = var.region
cluster_name = aws_eks_cluster.this[0].id
oidc {
client_id = each.value.client_id
groups_claim = lookup(each.value, "groups_claim", null)
groups_prefix = lookup(each.value, "groups_prefix", null)
groups_claim = each.value.groups_claim
groups_prefix = each.value.groups_prefix
identity_provider_config_name = try(each.value.identity_provider_config_name, each.key)
# TODO - make argument explicitly required on next breaking change
issuer_url = try(each.value.issuer_url, local.idpc_issuer_url)
required_claims = lookup(each.value, "required_claims", null)
username_claim = lookup(each.value, "username_claim", null)
username_prefix = lookup(each.value, "username_prefix", null)
issuer_url = each.value.issuer_url
required_claims = each.value.required_claims
username_claim = each.value.username_claim
username_prefix = each.value.username_prefix
}
tags = merge(var.tags, try(each.value.tags, {}))
tags = merge(
var.tags,
each.value.tags,
)
}
################################################################################
@@ -850,7 +875,7 @@ resource "aws_eks_identity_provider_config" "this" {
locals {
create_node_iam_role = local.create && var.create_node_iam_role && local.auto_mode_enabled
node_iam_role_name = coalesce(var.node_iam_role_name, "${var.cluster_name}-eks-auto")
node_iam_role_name = coalesce(var.node_iam_role_name, "${var.name}-eks-auto")
}
data "aws_iam_policy_document" "node_assume_role_policy" {
+3 -6
View File
@@ -9,7 +9,7 @@ See [`tests/user-data/`](https://github.com/terraform-aws-modules/terraform-aws-
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_cloudinit"></a> [cloudinit](#requirement\_cloudinit) | >= 2.0 |
| <a name="requirement_null"></a> [null](#requirement\_null) | >= 3.0 |
@@ -30,14 +30,14 @@ No modules.
|------|------|
| [null_resource.validate_cluster_service_cidr](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [cloudinit_config.al2023_eks_managed_node_group](https://registry.terraform.io/providers/hashicorp/cloudinit/latest/docs/data-sources/config) | data source |
| [cloudinit_config.linux_eks_managed_node_group](https://registry.terraform.io/providers/hashicorp/cloudinit/latest/docs/data-sources/config) | data source |
| [cloudinit_config.al2_eks_managed_node_group](https://registry.terraform.io/providers/hashicorp/cloudinit/latest/docs/data-sources/config) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_cluster_dns_ips"></a> [additional\_cluster\_dns\_ips](#input\_additional\_cluster\_dns\_ips) | Additional DNS IP addresses to use for the cluster. Only used when `ami_type` = `BOTTLEROCKET_*` | `list(string)` | `[]` | no |
| <a name="input_ami_type"></a> [ami\_type](#input\_ami\_type) | Type of Amazon Machine Image (AMI) associated with the EKS Node Group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values | `string` | `null` | no |
| <a name="input_ami_type"></a> [ami\_type](#input\_ami\_type) | Type of Amazon Machine Image (AMI) associated with the EKS Node Group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values | `string` | `"AL2023_x86_64_STANDARD"` | no |
| <a name="input_bootstrap_extra_args"></a> [bootstrap\_extra\_args](#input\_bootstrap\_extra\_args) | Additional arguments passed to the bootstrap script. When `ami_type` = `BOTTLEROCKET_*`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data | `string` | `""` | no |
| <a name="input_cloudinit_post_nodeadm"></a> [cloudinit\_post\_nodeadm](#input\_cloudinit\_post\_nodeadm) | Array of cloud-init document parts that are created after the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_cloudinit_pre_nodeadm"></a> [cloudinit\_pre\_nodeadm](#input\_cloudinit\_pre\_nodeadm) | Array of cloud-init document parts that are created before the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `[]` | no |
@@ -46,11 +46,9 @@ No modules.
| <a name="input_cluster_ip_family"></a> [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6` | `string` | `"ipv4"` | no |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | `""` | no |
| <a name="input_cluster_service_cidr"></a> [cluster\_service\_cidr](#input\_cluster\_service\_cidr) | The CIDR block (IPv4 or IPv6) used by the cluster to assign Kubernetes service IP addresses. This is derived from the cluster itself | `string` | `""` | no |
| <a name="input_cluster_service_ipv4_cidr"></a> [cluster\_service\_ipv4\_cidr](#input\_cluster\_service\_ipv4\_cidr) | [Deprecated] The CIDR block to assign Kubernetes service IP addresses from. If you don't specify a block, Kubernetes assigns addresses from either the 10.100.0.0/16 or 172.20.0.0/16 CIDR blocks | `string` | `null` | no |
| <a name="input_create"></a> [create](#input\_create) | Determines whether to create user-data or not | `bool` | `true` | no |
| <a name="input_enable_bootstrap_user_data"></a> [enable\_bootstrap\_user\_data](#input\_enable\_bootstrap\_user\_data) | Determines whether the bootstrap configurations are populated within the user data template | `bool` | `false` | no |
| <a name="input_is_eks_managed_node_group"></a> [is\_eks\_managed\_node\_group](#input\_is\_eks\_managed\_node\_group) | Determines whether the user data is used on nodes in an EKS managed node group. Used to determine if user data will be appended or not | `bool` | `true` | no |
| <a name="input_platform"></a> [platform](#input\_platform) | [DEPRECATED - use `ami_type` instead. Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023`, or `windows` | `string` | `"linux"` | no |
| <a name="input_post_bootstrap_user_data"></a> [post\_bootstrap\_user\_data](#input\_post\_bootstrap\_user\_data) | User data that is appended to the user data script after of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `""` | no |
| <a name="input_pre_bootstrap_user_data"></a> [pre\_bootstrap\_user\_data](#input\_pre\_bootstrap\_user\_data) | User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `""` | no |
| <a name="input_user_data_template_path"></a> [user\_data\_template\_path](#input\_user\_data\_template\_path) | Path to a local, custom user data template file to use when rendering user data | `string` | `""` | no |
@@ -59,6 +57,5 @@ No modules.
| Name | Description |
|------|-------------|
| <a name="output_platform"></a> [platform](#output\_platform) | [DEPRECATED - Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023, or `windows |
| <a name="output_user_data"></a> [user\_data](#output\_user\_data) | Base64 encoded user data rendered for the provided inputs |
<!-- END_TF_DOCS -->
+42 -55
View File
@@ -7,51 +7,47 @@ resource "null_resource" "validate_cluster_service_cidr" {
precondition {
# The length 6 is currently arbitrary, but it's a safe bet that the CIDR will be longer than that
# The main point is that a value needs to be provided when `create = true`
condition = var.create ? length(local.cluster_service_cidr) > 6 : true
condition = var.create ? length(var.cluster_service_cidr) > 6 : true
error_message = "`cluster_service_cidr` is required when `create = true`."
}
}
}
locals {
# Converts AMI type into user data type that represents the underlying format (bash, toml, PS1, nodeadm)
# TODO - platform will be removed in v21.0 and only `ami_type` will be valid
ami_type_to_user_data_type = {
AL2_x86_64 = "linux"
AL2_x86_64_GPU = "linux"
AL2_ARM_64 = "linux"
BOTTLEROCKET_ARM_64 = "bottlerocket"
BOTTLEROCKET_x86_64 = "bottlerocket"
BOTTLEROCKET_ARM_64_FIPS = "bottlerocket"
BOTTLEROCKET_x86_64_FIPS = "bottlerocket"
BOTTLEROCKET_ARM_64_NVIDIA = "bottlerocket"
BOTTLEROCKET_x86_64_NVIDIA = "bottlerocket"
WINDOWS_CORE_2019_x86_64 = "windows"
WINDOWS_FULL_2019_x86_64 = "windows"
WINDOWS_CORE_2022_x86_64 = "windows"
WINDOWS_FULL_2022_x86_64 = "windows"
AL2023_x86_64_STANDARD = "al2023"
AL2023_ARM_64_STANDARD = "al2023"
AL2023_x86_64_NEURON = "al2023"
AL2023_x86_64_NVIDIA = "al2023"
AL2023_ARM_64_NVIDIA = "al2023"
is_al2 = startswith(var.ami_type, "AL2_")
is_al2023 = startswith(var.ami_type, "AL2023_")
# Converts AMI type into user data template path
ami_type_to_user_data_path = {
AL2_ARM_64 = "${path.module}/../../templates/al2_user_data.tpl"
AL2_x86_64 = "${path.module}/../../templates/al2_user_data.tpl"
AL2_x86_64_GPU = "${path.module}/../../templates/al2_user_data.tpl"
AL2023_x86_64_STANDARD = "${path.module}/../../templates/al2023_user_data.tpl"
AL2023_ARM_64_STANDARD = "${path.module}/../../templates/al2023_user_data.tpl"
AL2023_x86_64_NEURON = "${path.module}/../../templates/al2023_user_data.tpl"
AL2023_x86_64_NVIDIA = "${path.module}/../../templates/al2023_user_data.tpl"
AL2023_ARM_64_NVIDIA = "${path.module}/../../templates/al2023_user_data.tpl"
BOTTLEROCKET_ARM_64 = "${path.module}/../../templates/bottlerocket_user_data.tpl"
BOTTLEROCKET_x86_64 = "${path.module}/../../templates/bottlerocket_user_data.tpl"
BOTTLEROCKET_ARM_64_FIPS = "${path.module}/../../templates/bottlerocket_user_data.tpl"
BOTTLEROCKET_x86_64_FIPS = "${path.module}/../../templates/bottlerocket_user_data.tpl"
BOTTLEROCKET_ARM_64_NVIDIA = "${path.module}/../../templates/bottlerocket_user_data.tpl"
BOTTLEROCKET_x86_64_NVIDIA = "${path.module}/../../templates/bottlerocket_user_data.tpl"
WINDOWS_CORE_2019_x86_64 = "${path.module}/../../templates/windows_user_data.tpl"
WINDOWS_FULL_2019_x86_64 = "${path.module}/../../templates/windows_user_data.tpl"
WINDOWS_CORE_2022_x86_64 = "${path.module}/../../templates/windows_user_data.tpl"
WINDOWS_FULL_2022_x86_64 = "${path.module}/../../templates/windows_user_data.tpl"
CUSTOM = var.user_data_template_path
}
# Try to use `ami_type` first, but fall back to current, default behavior
# TODO - will be removed in v21.0
user_data_type = try(local.ami_type_to_user_data_type[var.ami_type], var.platform)
user_data_path = coalesce(var.user_data_template_path, local.ami_type_to_user_data_path[var.ami_type])
template_path = {
al2023 = "${path.module}/../../templates/al2023_user_data.tpl"
bottlerocket = "${path.module}/../../templates/bottlerocket_user_data.tpl"
linux = "${path.module}/../../templates/linux_user_data.tpl"
windows = "${path.module}/../../templates/windows_user_data.tpl"
}
cluster_dns_ips = flatten(concat([try(cidrhost(var.cluster_service_cidr, 10), "")], var.additional_cluster_dns_ips))
cluster_service_cidr = try(coalesce(var.cluster_service_ipv4_cidr, var.cluster_service_cidr), "")
cluster_dns_ips = flatten(concat([try(cidrhost(local.cluster_service_cidr, 10), "")], var.additional_cluster_dns_ips))
user_data = base64encode(templatefile(
coalesce(var.user_data_template_path, local.template_path[local.user_data_type]),
user_data = var.create ? base64encode(templatefile(local.user_data_path,
{
# https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-custom-ami
enable_bootstrap_user_data = var.enable_bootstrap_user_data
@@ -61,7 +57,7 @@ locals {
cluster_endpoint = var.cluster_endpoint
cluster_auth_base64 = var.cluster_auth_base64
cluster_service_cidr = local.cluster_service_cidr
cluster_service_cidr = var.cluster_service_cidr
cluster_ip_family = var.cluster_ip_family
# Bottlerocket
@@ -72,22 +68,13 @@ locals {
pre_bootstrap_user_data = var.pre_bootstrap_user_data
post_bootstrap_user_data = var.post_bootstrap_user_data
}
))
)) : ""
user_data_type_to_rendered = {
al2023 = {
user_data = var.create ? try(data.cloudinit_config.al2023_eks_managed_node_group[0].rendered, local.user_data) : ""
}
bottlerocket = {
user_data = var.create && local.user_data_type == "bottlerocket" && (var.enable_bootstrap_user_data || var.user_data_template_path != "" || var.bootstrap_extra_args != "") ? local.user_data : ""
}
linux = {
user_data = var.create ? try(data.cloudinit_config.linux_eks_managed_node_group[0].rendered, local.user_data) : ""
}
windows = {
user_data = var.create && local.user_data_type == "windows" && (var.enable_bootstrap_user_data || var.user_data_template_path != "" || var.pre_bootstrap_user_data != "") ? local.user_data : ""
}
}
user_data_type_to_rendered = try(coalesce(
local.is_al2 ? try(data.cloudinit_config.al2_eks_managed_node_group[0].rendered, local.user_data) : null,
local.is_al2023 ? try(data.cloudinit_config.al2023_eks_managed_node_group[0].rendered, local.user_data) : null,
local.user_data,
), "")
}
# https://github.com/aws/containers-roadmap/issues/596#issuecomment-675097667
@@ -97,8 +84,8 @@ locals {
# this merging will NOT happen and you are responsible for nodes joining the cluster.
# See docs for more details -> https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-user-data
data "cloudinit_config" "linux_eks_managed_node_group" {
count = var.create && local.user_data_type == "linux" && var.is_eks_managed_node_group && !var.enable_bootstrap_user_data && var.pre_bootstrap_user_data != "" && var.user_data_template_path == "" ? 1 : 0
data "cloudinit_config" "al2_eks_managed_node_group" {
count = var.create && local.is_al2 && var.is_eks_managed_node_group && !var.enable_bootstrap_user_data && var.pre_bootstrap_user_data != "" && var.user_data_template_path == "" ? 1 : 0
base64_encode = true
gzip = false
@@ -129,7 +116,7 @@ locals {
}
data "cloudinit_config" "al2023_eks_managed_node_group" {
count = var.create && local.user_data_type == "al2023" && length(local.nodeadm_cloudinit) > 0 ? 1 : 0
count = var.create && local.is_al2023 && length(local.nodeadm_cloudinit) > 0 ? 1 : 0
base64_encode = true
gzip = false
+1 -6
View File
@@ -1,9 +1,4 @@
output "user_data" {
description = "Base64 encoded user data rendered for the provided inputs"
value = try(local.user_data_type_to_rendered[local.user_data_type].user_data, null)
}
output "platform" {
description = "[DEPRECATED - Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023, or `windows`"
value = local.user_data_type
value = local.user_data_type_to_rendered
}
+17 -14
View File
@@ -2,97 +2,98 @@ variable "create" {
description = "Determines whether to create user-data or not"
type = bool
default = true
}
variable "platform" {
description = "[DEPRECATED - use `ami_type` instead. Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023`, or `windows`"
type = string
default = "linux"
nullable = false
}
variable "ami_type" {
description = "Type of Amazon Machine Image (AMI) associated with the EKS Node Group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values"
type = string
default = null
default = "AL2023_x86_64_STANDARD"
nullable = false
}
variable "enable_bootstrap_user_data" {
description = "Determines whether the bootstrap configurations are populated within the user data template"
type = bool
default = false
nullable = false
}
variable "is_eks_managed_node_group" {
description = "Determines whether the user data is used on nodes in an EKS managed node group. Used to determine if user data will be appended or not"
type = bool
default = true
nullable = false
}
variable "cluster_name" {
description = "Name of the EKS cluster"
type = string
default = ""
nullable = false
}
variable "cluster_endpoint" {
description = "Endpoint of associated EKS cluster"
type = string
default = ""
nullable = false
}
variable "cluster_auth_base64" {
description = "Base64 encoded CA of associated EKS cluster"
type = string
default = ""
nullable = false
}
variable "cluster_service_cidr" {
description = "The CIDR block (IPv4 or IPv6) used by the cluster to assign Kubernetes service IP addresses. This is derived from the cluster itself"
type = string
default = ""
nullable = false
}
variable "cluster_ip_family" {
description = "The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6`"
type = string
default = "ipv4"
nullable = false
}
variable "additional_cluster_dns_ips" {
description = "Additional DNS IP addresses to use for the cluster. Only used when `ami_type` = `BOTTLEROCKET_*`"
type = list(string)
default = []
}
# TODO - remove at next breaking change
variable "cluster_service_ipv4_cidr" {
description = "[Deprecated] The CIDR block to assign Kubernetes service IP addresses from. If you don't specify a block, Kubernetes assigns addresses from either the 10.100.0.0/16 or 172.20.0.0/16 CIDR blocks"
type = string
default = null
nullable = false
}
variable "pre_bootstrap_user_data" {
description = "User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*`"
type = string
default = ""
nullable = false
}
variable "post_bootstrap_user_data" {
description = "User data that is appended to the user data script after of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*`"
type = string
default = ""
nullable = false
}
variable "bootstrap_extra_args" {
description = "Additional arguments passed to the bootstrap script. When `ami_type` = `BOTTLEROCKET_*`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data"
type = string
default = ""
nullable = false
}
variable "user_data_template_path" {
description = "Path to a local, custom user data template file to use when rendering user data"
type = string
default = ""
nullable = false
}
variable "cloudinit_pre_nodeadm" {
@@ -104,6 +105,7 @@ variable "cloudinit_pre_nodeadm" {
merge_type = optional(string)
}))
default = []
nullable = false
}
variable "cloudinit_post_nodeadm" {
@@ -115,4 +117,5 @@ variable "cloudinit_post_nodeadm" {
merge_type = optional(string)
}))
default = []
nullable = false
}
+1 -1
View File
@@ -1,5 +1,5 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
cloudinit = {
-81
View File
@@ -1,81 +0,0 @@
# `aws-auth` Module
Configuration in this directory creates/updates the `aws-auth` ConfigMap.
```hcl
module "eks" {
source = "terraform-aws-modules/eks/aws//modules/aws-auth"
version = "~> 20.0"
manage_aws_auth_configmap = true
aws_auth_roles = [
{
rolearn = "arn:aws:iam::66666666666:role/role1"
username = "role1"
groups = ["system:masters"]
},
]
aws_auth_users = [
{
userarn = "arn:aws:iam::66666666666:user/user1"
username = "user1"
groups = ["system:masters"]
},
{
userarn = "arn:aws:iam::66666666666:user/user2"
username = "user2"
groups = ["system:masters"]
},
]
aws_auth_accounts = [
"777777777777",
"888888888888",
]
}
```
## Usage
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_kubernetes"></a> [kubernetes](#requirement\_kubernetes) | >= 2.20 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | >= 2.20 |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [kubernetes_config_map.aws_auth](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | resource |
| [kubernetes_config_map_v1_data.aws_auth](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map_v1_data) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_aws_auth_accounts"></a> [aws\_auth\_accounts](#input\_aws\_auth\_accounts) | List of account maps to add to the aws-auth configmap | `list(any)` | `[]` | no |
| <a name="input_aws_auth_roles"></a> [aws\_auth\_roles](#input\_aws\_auth\_roles) | List of role maps to add to the aws-auth configmap | `list(any)` | `[]` | no |
| <a name="input_aws_auth_users"></a> [aws\_auth\_users](#input\_aws\_auth\_users) | List of user maps to add to the aws-auth configmap | `list(any)` | `[]` | no |
| <a name="input_create"></a> [create](#input\_create) | Controls if resources should be created (affects all resources) | `bool` | `true` | no |
| <a name="input_create_aws_auth_configmap"></a> [create\_aws\_auth\_configmap](#input\_create\_aws\_auth\_configmap) | Determines whether to create the aws-auth configmap. NOTE - this is only intended for scenarios where the configmap does not exist (i.e. - when using only self-managed node groups). Most users should use `manage_aws_auth_configmap` | `bool` | `false` | no |
| <a name="input_manage_aws_auth_configmap"></a> [manage\_aws\_auth\_configmap](#input\_manage\_aws\_auth\_configmap) | Determines whether to manage the aws-auth configmap | `bool` | `true` | no |
## Outputs
No outputs.
<!-- END_TF_DOCS -->
-47
View File
@@ -1,47 +0,0 @@
################################################################################
# aws-auth configmap
################################################################################
locals {
aws_auth_configmap_data = {
mapRoles = yamlencode(var.aws_auth_roles)
mapUsers = yamlencode(var.aws_auth_users)
mapAccounts = yamlencode(var.aws_auth_accounts)
}
}
resource "kubernetes_config_map" "aws_auth" {
count = var.create && var.create_aws_auth_configmap ? 1 : 0
metadata {
name = "aws-auth"
namespace = "kube-system"
}
data = local.aws_auth_configmap_data
lifecycle {
# We are ignoring the data here since we will manage it with the resource below
# This is only intended to be used in scenarios where the configmap does not exist
ignore_changes = [data, metadata[0].labels, metadata[0].annotations]
}
}
resource "kubernetes_config_map_v1_data" "aws_auth" {
count = var.create && var.manage_aws_auth_configmap ? 1 : 0
force = true
metadata {
name = "aws-auth"
namespace = "kube-system"
}
data = local.aws_auth_configmap_data
depends_on = [
# Required for instances where the configmap does not exist yet to avoid race condition
kubernetes_config_map.aws_auth,
]
}
View File
-39
View File
@@ -1,39 +0,0 @@
variable "create" {
description = "Controls if resources should be created (affects all resources)"
type = bool
default = true
}
################################################################################
# aws-auth ConfigMap
################################################################################
variable "create_aws_auth_configmap" {
description = "Determines whether to create the aws-auth configmap. NOTE - this is only intended for scenarios where the configmap does not exist (i.e. - when using only self-managed node groups). Most users should use `manage_aws_auth_configmap`"
type = bool
default = false
}
variable "manage_aws_auth_configmap" {
description = "Determines whether to manage the aws-auth configmap"
type = bool
default = true
}
variable "aws_auth_roles" {
description = "List of role maps to add to the aws-auth configmap"
type = list(any)
default = []
}
variable "aws_auth_users" {
description = "List of user maps to add to the aws-auth configmap"
type = list(any)
default = []
}
variable "aws_auth_accounts" {
description = "List of account maps to add to the aws-auth configmap"
type = list(any)
default = []
}
-10
View File
@@ -1,10 +0,0 @@
terraform {
required_version = ">= 1.3.2"
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.20"
}
}
}
+54 -50
View File
@@ -63,14 +63,14 @@ module "eks_managed_node_group" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -82,7 +82,6 @@ module "eks_managed_node_group" {
| Name | Type |
|------|------|
| [aws_autoscaling_schedule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource |
| [aws_eks_node_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group) | resource |
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
@@ -90,71 +89,72 @@ module "eks_managed_node_group" {
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource |
| [aws_placement_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/placement_group) | resource |
| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
| [aws_vpc_security_group_egress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource |
| [aws_vpc_security_group_ingress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_ec2_instance_type.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type) | data source |
| [aws_ec2_instance_type_offerings.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type_offerings) | data source |
| [aws_eks_cluster_versions.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster_versions) | data source |
| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
| [aws_ssm_parameter.ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source |
| [aws_subnets.placement_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source |
| [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_account_id"></a> [account\_id](#input\_account\_id) | The AWS account ID - pass through value to reduce number of GET requests from data sources | `string` | `""` | no |
| <a name="input_ami_id"></a> [ami\_id](#input\_ami\_id) | The AMI from which to launch the instance. If not supplied, EKS will use its own default image | `string` | `""` | no |
| <a name="input_ami_release_version"></a> [ami\_release\_version](#input\_ami\_release\_version) | The AMI version. Defaults to latest AMI release version for the given Kubernetes version and AMI type | `string` | `null` | no |
| <a name="input_ami_type"></a> [ami\_type](#input\_ami\_type) | Type of Amazon Machine Image (AMI) associated with the EKS Node Group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values | `string` | `null` | no |
| <a name="input_block_device_mappings"></a> [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI | `any` | `{}` | no |
| <a name="input_bootstrap_extra_args"></a> [bootstrap\_extra\_args](#input\_bootstrap\_extra\_args) | Additional arguments passed to the bootstrap script. When `ami_type` = `BOTTLEROCKET_*`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data | `string` | `""` | no |
| <a name="input_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Targeting for EC2 capacity reservations | `any` | `{}` | no |
| <a name="input_ami_type"></a> [ami\_type](#input\_ami\_type) | Type of Amazon Machine Image (AMI) associated with the EKS Node Group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values | `string` | `"AL2023_x86_64_STANDARD"` | no |
| <a name="input_block_device_mappings"></a> [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI | <pre>map(object({<br/> device_name = optional(string)<br/> ebs = optional(object({<br/> delete_on_termination = optional(bool)<br/> encrypted = optional(bool)<br/> iops = optional(number)<br/> kms_key_id = optional(string)<br/> snapshot_id = optional(string)<br/> throughput = optional(number)<br/> volume_initialization_rate = optional(number)<br/> volume_size = optional(number)<br/> volume_type = optional(string)<br/> }))<br/> no_device = optional(string)<br/> virtual_name = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_bootstrap_extra_args"></a> [bootstrap\_extra\_args](#input\_bootstrap\_extra\_args) | Additional arguments passed to the bootstrap script. When `ami_type` = `BOTTLEROCKET_*`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data | `string` | `null` | no |
| <a name="input_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Targeting for EC2 capacity reservations | <pre>object({<br/> capacity_reservation_preference = optional(string)<br/> capacity_reservation_target = optional(object({<br/> capacity_reservation_id = optional(string)<br/> capacity_reservation_resource_group_arn = optional(string)<br/> }))<br/> })</pre> | `null` | no |
| <a name="input_capacity_type"></a> [capacity\_type](#input\_capacity\_type) | Type of capacity associated with the EKS Node Group. Valid values: `ON_DEMAND`, `SPOT` | `string` | `"ON_DEMAND"` | no |
| <a name="input_cloudinit_post_nodeadm"></a> [cloudinit\_post\_nodeadm](#input\_cloudinit\_post\_nodeadm) | Array of cloud-init document parts that are created after the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_cloudinit_pre_nodeadm"></a> [cloudinit\_pre\_nodeadm](#input\_cloudinit\_pre\_nodeadm) | Array of cloud-init document parts that are created before the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_cluster_auth_base64"></a> [cluster\_auth\_base64](#input\_cluster\_auth\_base64) | Base64 encoded CA of associated EKS cluster | `string` | `""` | no |
| <a name="input_cluster_endpoint"></a> [cluster\_endpoint](#input\_cluster\_endpoint) | Endpoint of associated EKS cluster | `string` | `""` | no |
| <a name="input_cloudinit_post_nodeadm"></a> [cloudinit\_post\_nodeadm](#input\_cloudinit\_post\_nodeadm) | Array of cloud-init document parts that are created after the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_cloudinit_pre_nodeadm"></a> [cloudinit\_pre\_nodeadm](#input\_cloudinit\_pre\_nodeadm) | Array of cloud-init document parts that are created before the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_cluster_auth_base64"></a> [cluster\_auth\_base64](#input\_cluster\_auth\_base64) | Base64 encoded CA of associated EKS cluster | `string` | `null` | no |
| <a name="input_cluster_endpoint"></a> [cluster\_endpoint](#input\_cluster\_endpoint) | Endpoint of associated EKS cluster | `string` | `null` | no |
| <a name="input_cluster_ip_family"></a> [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6` | `string` | `"ipv4"` | no |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of associated EKS cluster | `string` | `null` | no |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of associated EKS cluster | `string` | `""` | no |
| <a name="input_cluster_primary_security_group_id"></a> [cluster\_primary\_security\_group\_id](#input\_cluster\_primary\_security\_group\_id) | The ID of the EKS cluster primary security group to associate with the instance(s). This is the security group that is automatically created by the EKS service | `string` | `null` | no |
| <a name="input_cluster_service_cidr"></a> [cluster\_service\_cidr](#input\_cluster\_service\_cidr) | The CIDR block (IPv4 or IPv6) used by the cluster to assign Kubernetes service IP addresses. This is derived from the cluster itself | `string` | `""` | no |
| <a name="input_cluster_service_ipv4_cidr"></a> [cluster\_service\_ipv4\_cidr](#input\_cluster\_service\_ipv4\_cidr) | [Deprecated] The CIDR block to assign Kubernetes service IP addresses from. If you don't specify a block, Kubernetes assigns addresses from either the 10.100.0.0/16 or 172.20.0.0/16 CIDR blocks | `string` | `null` | no |
| <a name="input_cluster_version"></a> [cluster\_version](#input\_cluster\_version) | Kubernetes version. Defaults to EKS Cluster Kubernetes version | `string` | `null` | no |
| <a name="input_cpu_options"></a> [cpu\_options](#input\_cpu\_options) | The CPU options for the instance | `map(string)` | `{}` | no |
| <a name="input_cluster_service_cidr"></a> [cluster\_service\_cidr](#input\_cluster\_service\_cidr) | The CIDR block (IPv4 or IPv6) used by the cluster to assign Kubernetes service IP addresses. This is derived from the cluster itself | `string` | `null` | no |
| <a name="input_cpu_options"></a> [cpu\_options](#input\_cpu\_options) | The CPU options for the instance | <pre>object({<br/> amd_sev_snp = optional(string)<br/> core_count = optional(number)<br/> threads_per_core = optional(number)<br/> })</pre> | `null` | no |
| <a name="input_create"></a> [create](#input\_create) | Determines whether to create EKS managed node group or not | `bool` | `true` | no |
| <a name="input_create_iam_role"></a> [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created or to use an existing IAM role | `bool` | `true` | no |
| <a name="input_create_iam_role_policy"></a> [create\_iam\_role\_policy](#input\_create\_iam\_role\_policy) | Determines whether an IAM role policy is created or not | `bool` | `true` | no |
| <a name="input_create_launch_template"></a> [create\_launch\_template](#input\_create\_launch\_template) | Determines whether to create a launch template or not. If set to `false`, EKS will use its own default launch template | `bool` | `true` | no |
| <a name="input_create_placement_group"></a> [create\_placement\_group](#input\_create\_placement\_group) | Determines whether a placement group is created & used by the node group | `bool` | `false` | no |
| <a name="input_create_schedule"></a> [create\_schedule](#input\_create\_schedule) | Determines whether to create autoscaling group schedule or not | `bool` | `true` | no |
| <a name="input_credit_specification"></a> [credit\_specification](#input\_credit\_specification) | Customize the credit specification of the instance | `map(string)` | `{}` | no |
| <a name="input_create_security_group"></a> [create\_security\_group](#input\_create\_security\_group) | Determines if a security group is created | `bool` | `true` | no |
| <a name="input_credit_specification"></a> [credit\_specification](#input\_credit\_specification) | Customize the credit specification of the instance | <pre>object({<br/> cpu_credits = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_desired_size"></a> [desired\_size](#input\_desired\_size) | Desired number of instances/nodes | `number` | `1` | no |
| <a name="input_disable_api_termination"></a> [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 instance termination protection | `bool` | `null` | no |
| <a name="input_disk_size"></a> [disk\_size](#input\_disk\_size) | Disk size in GiB for nodes. Defaults to `20`. Only valid when `use_custom_launch_template` = `false` | `number` | `null` | no |
| <a name="input_ebs_optimized"></a> [ebs\_optimized](#input\_ebs\_optimized) | If true, the launched EC2 instance(s) will be EBS-optimized | `bool` | `null` | no |
| <a name="input_efa_indices"></a> [efa\_indices](#input\_efa\_indices) | The indices of the network interfaces that should be EFA-enabled. Only valid when `enable_efa_support` = `true` | `list(number)` | <pre>[<br/> 0<br/>]</pre> | no |
| <a name="input_elastic_gpu_specifications"></a> [elastic\_gpu\_specifications](#input\_elastic\_gpu\_specifications) | The elastic GPU to attach to the instance | `any` | `{}` | no |
| <a name="input_elastic_inference_accelerator"></a> [elastic\_inference\_accelerator](#input\_elastic\_inference\_accelerator) | Configuration block containing an Elastic Inference Accelerator to attach to the instance | `map(string)` | `{}` | no |
| <a name="input_enable_bootstrap_user_data"></a> [enable\_bootstrap\_user\_data](#input\_enable\_bootstrap\_user\_data) | Determines whether the bootstrap configurations are populated within the user data template. Only valid when using a custom AMI via `ami_id` | `bool` | `false` | no |
| <a name="input_enable_efa_only"></a> [enable\_efa\_only](#input\_enable\_efa\_only) | Determines whether to enable EFA (`false`, default) or EFA and EFA-only (`true`) network interfaces. Note: requires vpc-cni version `v1.18.4` or later | `bool` | `false` | no |
| <a name="input_enable_efa_only"></a> [enable\_efa\_only](#input\_enable\_efa\_only) | Determines whether to enable EFA (`false`, default) or EFA and EFA-only (`true`) network interfaces. Note: requires vpc-cni version `v1.18.4` or later | `bool` | `true` | no |
| <a name="input_enable_efa_support"></a> [enable\_efa\_support](#input\_enable\_efa\_support) | Determines whether to enable Elastic Fabric Adapter (EFA) support | `bool` | `false` | no |
| <a name="input_enable_monitoring"></a> [enable\_monitoring](#input\_enable\_monitoring) | Enables/disables detailed monitoring | `bool` | `true` | no |
| <a name="input_enclave_options"></a> [enclave\_options](#input\_enclave\_options) | Enable Nitro Enclaves on launched instances | `map(string)` | `{}` | no |
| <a name="input_enable_monitoring"></a> [enable\_monitoring](#input\_enable\_monitoring) | Enables/disables detailed monitoring | `bool` | `false` | no |
| <a name="input_enclave_options"></a> [enclave\_options](#input\_enclave\_options) | Enable Nitro Enclaves on launched instances | <pre>object({<br/> enabled = optional(bool)<br/> })</pre> | `null` | no |
| <a name="input_force_update_version"></a> [force\_update\_version](#input\_force\_update\_version) | Force version update if existing pods are unable to be drained due to a pod disruption budget issue | `bool` | `null` | no |
| <a name="input_iam_role_additional_policies"></a> [iam\_role\_additional\_policies](#input\_iam\_role\_additional\_policies) | Additional policies to be added to the IAM role | `map(string)` | `{}` | no |
| <a name="input_iam_role_arn"></a> [iam\_role\_arn](#input\_iam\_role\_arn) | Existing IAM role ARN for the node group. Required if `create_iam_role` is set to `false` | `string` | `null` | no |
| <a name="input_iam_role_attach_cni_policy"></a> [iam\_role\_attach\_cni\_policy](#input\_iam\_role\_attach\_cni\_policy) | Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster | `bool` | `true` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `"EKS managed node group IAM role"` | no |
| <a name="input_iam_role_name"></a> [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no |
| <a name="input_iam_role_path"></a> [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no |
| <a name="input_iam_role_permissions_boundary"></a> [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no |
| <a name="input_iam_role_policy_statements"></a> [iam\_role\_policy\_statements](#input\_iam\_role\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
| <a name="input_iam_role_policy_statements"></a> [iam\_role\_policy\_statements](#input\_iam\_role\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | <pre>list(object({<br/> sid = optional(string)<br/> actions = optional(list(string))<br/> not_actions = optional(list(string))<br/> effect = optional(string)<br/> resources = optional(list(string))<br/> not_resources = optional(list(string))<br/> principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> not_principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> condition = optional(list(object({<br/> test = string<br/> values = list(string)<br/> variable = string<br/> })))<br/> }))</pre> | `null` | no |
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role created | `map(string)` | `{}` | no |
| <a name="input_iam_role_use_name_prefix"></a> [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the IAM role name (`iam_role_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_instance_market_options"></a> [instance\_market\_options](#input\_instance\_market\_options) | The market (purchasing) option for the instance | `any` | `{}` | no |
| <a name="input_instance_market_options"></a> [instance\_market\_options](#input\_instance\_market\_options) | The market (purchasing) option for the instance | <pre>object({<br/> market_type = optional(string)<br/> spot_options = optional(object({<br/> block_duration_minutes = optional(number)<br/> instance_interruption_behavior = optional(string)<br/> max_price = optional(string)<br/> spot_instance_type = optional(string)<br/> valid_until = optional(string)<br/> }))<br/> })</pre> | `null` | no |
| <a name="input_instance_types"></a> [instance\_types](#input\_instance\_types) | Set of instance types associated with the EKS Node Group. Defaults to `["t3.medium"]` | `list(string)` | `null` | no |
| <a name="input_kernel_id"></a> [kernel\_id](#input\_kernel\_id) | The kernel ID | `string` | `null` | no |
| <a name="input_key_name"></a> [key\_name](#input\_key\_name) | The key name that should be used for the instance(s) | `string` | `null` | no |
| <a name="input_kubernetes_version"></a> [kubernetes\_version](#input\_kubernetes\_version) | Kubernetes version. Defaults to EKS Cluster Kubernetes version | `string` | `null` | no |
| <a name="input_labels"></a> [labels](#input\_labels) | Key-value map of Kubernetes labels. Only labels that are applied with the EKS API are managed by this argument. Other Kubernetes labels applied to the EKS Node Group will not be managed | `map(string)` | `null` | no |
| <a name="input_launch_template_default_version"></a> [launch\_template\_default\_version](#input\_launch\_template\_default\_version) | Default version of the launch template | `string` | `null` | no |
| <a name="input_launch_template_description"></a> [launch\_template\_description](#input\_launch\_template\_description) | Description of the launch template | `string` | `null` | no |
@@ -163,42 +163,45 @@ module "eks_managed_node_group" {
| <a name="input_launch_template_tags"></a> [launch\_template\_tags](#input\_launch\_template\_tags) | A map of additional tags to add to the tag\_specifications of launch template created | `map(string)` | `{}` | no |
| <a name="input_launch_template_use_name_prefix"></a> [launch\_template\_use\_name\_prefix](#input\_launch\_template\_use\_name\_prefix) | Determines whether to use `launch_template_name` as is or create a unique name beginning with the `launch_template_name` as the prefix | `bool` | `true` | no |
| <a name="input_launch_template_version"></a> [launch\_template\_version](#input\_launch\_template\_version) | Launch template version number. The default is `$Default` | `string` | `null` | no |
| <a name="input_license_specifications"></a> [license\_specifications](#input\_license\_specifications) | A map of license specifications to associate with | `any` | `{}` | no |
| <a name="input_maintenance_options"></a> [maintenance\_options](#input\_maintenance\_options) | The maintenance options for the instance | `any` | `{}` | no |
| <a name="input_license_specifications"></a> [license\_specifications](#input\_license\_specifications) | A list of license specifications to associate with | <pre>list(object({<br/> license_configuration_arn = string<br/> }))</pre> | `null` | no |
| <a name="input_maintenance_options"></a> [maintenance\_options](#input\_maintenance\_options) | The maintenance options for the instance | <pre>object({<br/> auto_recovery = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_max_size"></a> [max\_size](#input\_max\_size) | Maximum number of instances/nodes | `number` | `3` | no |
| <a name="input_metadata_options"></a> [metadata\_options](#input\_metadata\_options) | Customize the metadata options for the instance | `map(string)` | <pre>{<br/> "http_endpoint": "enabled",<br/> "http_put_response_hop_limit": 2,<br/> "http_tokens": "required"<br/>}</pre> | no |
| <a name="input_min_size"></a> [min\_size](#input\_min\_size) | Minimum number of instances/nodes | `number` | `0` | no |
| <a name="input_metadata_options"></a> [metadata\_options](#input\_metadata\_options) | Customize the metadata options for the instance | <pre>object({<br/> http_endpoint = optional(string, "enabled")<br/> http_protocol_ipv6 = optional(string)<br/> http_put_response_hop_limit = optional(number, 1)<br/> http_tokens = optional(string, "required")<br/> instance_metadata_tags = optional(string)<br/> })</pre> | <pre>{<br/> "http_endpoint": "enabled",<br/> "http_put_response_hop_limit": 1,<br/> "http_tokens": "required"<br/>}</pre> | no |
| <a name="input_min_size"></a> [min\_size](#input\_min\_size) | Minimum number of instances/nodes | `number` | `1` | no |
| <a name="input_name"></a> [name](#input\_name) | Name of the EKS managed node group | `string` | `""` | no |
| <a name="input_network_interfaces"></a> [network\_interfaces](#input\_network\_interfaces) | Customize network interfaces to be attached at instance boot time | `list(any)` | `[]` | no |
| <a name="input_network_interfaces"></a> [network\_interfaces](#input\_network\_interfaces) | Customize network interfaces to be attached at instance boot time | <pre>list(object({<br/> associate_carrier_ip_address = optional(bool)<br/> associate_public_ip_address = optional(bool)<br/> connection_tracking_specification = optional(object({<br/> tcp_established_timeout = optional(number)<br/> udp_stream_timeout = optional(number)<br/> udp_timeout = optional(number)<br/> }))<br/> delete_on_termination = optional(bool)<br/> description = optional(string)<br/> device_index = optional(number)<br/> ena_srd_specification = optional(object({<br/> ena_srd_enabled = optional(bool)<br/> ena_srd_udp_specification = optional(object({<br/> ena_srd_udp_enabled = optional(bool)<br/> }))<br/> }))<br/> interface_type = optional(string)<br/> ipv4_address_count = optional(number)<br/> ipv4_addresses = optional(list(string))<br/> ipv4_prefix_count = optional(number)<br/> ipv4_prefixes = optional(list(string))<br/> ipv6_address_count = optional(number)<br/> ipv6_addresses = optional(list(string))<br/> ipv6_prefix_count = optional(number)<br/> ipv6_prefixes = optional(list(string))<br/> network_card_index = optional(number)<br/> network_interface_id = optional(string)<br/> primary_ipv6 = optional(bool)<br/> private_ip_address = optional(string)<br/> security_groups = optional(list(string), [])<br/> subnet_id = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_node_repair_config"></a> [node\_repair\_config](#input\_node\_repair\_config) | The node auto repair configuration for the node group | <pre>object({<br/> enabled = optional(bool, true)<br/> })</pre> | `null` | no |
| <a name="input_placement"></a> [placement](#input\_placement) | The placement of the instance | `map(string)` | `{}` | no |
| <a name="input_placement_group_az"></a> [placement\_group\_az](#input\_placement\_group\_az) | Availability zone where placement group is created (ex. `eu-west-1c`) | `string` | `null` | no |
| <a name="input_placement_group_strategy"></a> [placement\_group\_strategy](#input\_placement\_group\_strategy) | The placement group strategy | `string` | `"cluster"` | no |
| <a name="input_platform"></a> [platform](#input\_platform) | [DEPRECATED - use `ami_type` instead. Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023`, or `windows` | `string` | `"linux"` | no |
| <a name="input_post_bootstrap_user_data"></a> [post\_bootstrap\_user\_data](#input\_post\_bootstrap\_user\_data) | User data that is appended to the user data script after of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `""` | no |
| <a name="input_pre_bootstrap_user_data"></a> [pre\_bootstrap\_user\_data](#input\_pre\_bootstrap\_user\_data) | User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `""` | no |
| <a name="input_private_dns_name_options"></a> [private\_dns\_name\_options](#input\_private\_dns\_name\_options) | The options for the instance hostname. The default values are inherited from the subnet | `map(string)` | `{}` | no |
| <a name="input_partition"></a> [partition](#input\_partition) | The AWS partition - pass through value to reduce number of GET requests from data sources | `string` | `""` | no |
| <a name="input_placement"></a> [placement](#input\_placement) | The placement of the instance | <pre>object({<br/> affinity = optional(string)<br/> availability_zone = optional(string)<br/> group_name = optional(string)<br/> host_id = optional(string)<br/> host_resource_group_arn = optional(string)<br/> partition_number = optional(number)<br/> spread_domain = optional(string)<br/> tenancy = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_post_bootstrap_user_data"></a> [post\_bootstrap\_user\_data](#input\_post\_bootstrap\_user\_data) | User data that is appended to the user data script after of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `null` | no |
| <a name="input_pre_bootstrap_user_data"></a> [pre\_bootstrap\_user\_data](#input\_pre\_bootstrap\_user\_data) | User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `null` | no |
| <a name="input_private_dns_name_options"></a> [private\_dns\_name\_options](#input\_private\_dns\_name\_options) | The options for the instance hostname. The default values are inherited from the subnet | <pre>object({<br/> enable_resource_name_dns_aaaa_record = optional(bool)<br/> enable_resource_name_dns_a_record = optional(bool)<br/> hostname_type = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_ram_disk_id"></a> [ram\_disk\_id](#input\_ram\_disk\_id) | The ID of the ram disk | `string` | `null` | no |
| <a name="input_remote_access"></a> [remote\_access](#input\_remote\_access) | Configuration block with remote access settings. Only valid when `use_custom_launch_template` = `false` | `any` | `{}` | no |
| <a name="input_schedules"></a> [schedules](#input\_schedules) | Map of autoscaling group schedule to create | `map(any)` | `{}` | no |
| <a name="input_region"></a> [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no |
| <a name="input_remote_access"></a> [remote\_access](#input\_remote\_access) | Configuration block with remote access settings. Only valid when `use_custom_launch_template` = `false` | <pre>object({<br/> ec2_ssh_key = optional(string)<br/> source_security_group_ids = optional(list(string))<br/> })</pre> | `null` | no |
| <a name="input_security_group_description"></a> [security\_group\_description](#input\_security\_group\_description) | Description of the security group created | `string` | `null` | no |
| <a name="input_security_group_egress_rules"></a> [security\_group\_egress\_rules](#input\_security\_group\_egress\_rules) | Security group egress rules to add to the security group created | <pre>map(object({<br/> name = optional(string)<br/><br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(string)<br/> ip_protocol = optional(string, "tcp")<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> self = optional(bool, false)<br/> tags = optional(map(string), {})<br/> to_port = optional(string)<br/> }))</pre> | `{}` | no |
| <a name="input_security_group_ingress_rules"></a> [security\_group\_ingress\_rules](#input\_security\_group\_ingress\_rules) | Security group ingress rules to add to the security group created | <pre>map(object({<br/> name = optional(string)<br/><br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(string)<br/> ip_protocol = optional(string, "tcp")<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> self = optional(bool, false)<br/> tags = optional(map(string), {})<br/> to_port = optional(string)<br/> }))</pre> | `{}` | no |
| <a name="input_security_group_name"></a> [security\_group\_name](#input\_security\_group\_name) | Name to use on security group created | `string` | `null` | no |
| <a name="input_security_group_tags"></a> [security\_group\_tags](#input\_security\_group\_tags) | A map of additional tags to add to the security group created | `map(string)` | `{}` | no |
| <a name="input_security_group_use_name_prefix"></a> [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`security_group_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | Identifiers of EC2 Subnets to associate with the EKS Node Group. These subnets must have the following resource tag: `kubernetes.io/cluster/CLUSTER_NAME` | `list(string)` | `null` | no |
| <a name="input_tag_specifications"></a> [tag\_specifications](#input\_tag\_specifications) | The tags to apply to the resources during launch | `list(string)` | <pre>[<br/> "instance",<br/> "volume",<br/> "network-interface"<br/>]</pre> | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
| <a name="input_taints"></a> [taints](#input\_taints) | The Kubernetes taints to be applied to the nodes in the node group. Maximum of 50 taints per node group | `any` | `{}` | no |
| <a name="input_timeouts"></a> [timeouts](#input\_timeouts) | Create, update, and delete timeout configurations for the node group | `map(string)` | `{}` | no |
| <a name="input_update_config"></a> [update\_config](#input\_update\_config) | Configuration block of settings for max unavailable resources during node group updates | `map(string)` | <pre>{<br/> "max_unavailable_percentage": 33<br/>}</pre> | no |
| <a name="input_taints"></a> [taints](#input\_taints) | The Kubernetes taints to be applied to the nodes in the node group. Maximum of 50 taints per node group | <pre>map(object({<br/> key = string<br/> value = optional(string)<br/> effect = string<br/> }))</pre> | `null` | no |
| <a name="input_timeouts"></a> [timeouts](#input\_timeouts) | Create, update, and delete timeout configurations for the node group | <pre>object({<br/> create = optional(string)<br/> update = optional(string)<br/> delete = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_update_config"></a> [update\_config](#input\_update\_config) | Configuration block of settings for max unavailable resources during node group updates | <pre>object({<br/> max_unavailable = optional(number)<br/> max_unavailable_percentage = optional(number)<br/> })</pre> | <pre>{<br/> "max_unavailable_percentage": 33<br/>}</pre> | no |
| <a name="input_update_launch_template_default_version"></a> [update\_launch\_template\_default\_version](#input\_update\_launch\_template\_default\_version) | Whether to update the launch templates default version on each update. Conflicts with `launch_template_default_version` | `bool` | `true` | no |
| <a name="input_use_custom_launch_template"></a> [use\_custom\_launch\_template](#input\_use\_custom\_launch\_template) | Determines whether to use a custom launch template or not. If set to `false`, EKS will use its own default launch template | `bool` | `true` | no |
| <a name="input_use_latest_ami_release_version"></a> [use\_latest\_ami\_release\_version](#input\_use\_latest\_ami\_release\_version) | Determines whether to use the latest AMI release version for the given `ami_type` (except for `CUSTOM`). Note: `ami_type` and `cluster_version` must be supplied in order to enable this feature | `bool` | `false` | no |
| <a name="input_use_latest_ami_release_version"></a> [use\_latest\_ami\_release\_version](#input\_use\_latest\_ami\_release\_version) | Determines whether to use the latest AMI release version for the given `ami_type` (except for `CUSTOM`). Note: `ami_type` and `kubernetes_version` must be supplied in order to enable this feature | `bool` | `true` | no |
| <a name="input_use_name_prefix"></a> [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix | `bool` | `true` | no |
| <a name="input_user_data_template_path"></a> [user\_data\_template\_path](#input\_user\_data\_template\_path) | Path to a local, custom user data template file to use when rendering user data | `string` | `""` | no |
| <a name="input_user_data_template_path"></a> [user\_data\_template\_path](#input\_user\_data\_template\_path) | Path to a local, custom user data template file to use when rendering user data | `string` | `null` | no |
| <a name="input_vpc_security_group_ids"></a> [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | A list of security group IDs to associate | `list(string)` | `[]` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_autoscaling_group_schedule_arns"></a> [autoscaling\_group\_schedule\_arns](#output\_autoscaling\_group\_schedule\_arns) | ARNs of autoscaling group schedules |
| <a name="output_iam_role_arn"></a> [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role |
| <a name="output_iam_role_name"></a> [iam\_role\_name](#output\_iam\_role\_name) | The name of the IAM role |
| <a name="output_iam_role_unique_id"></a> [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role |
@@ -213,5 +216,6 @@ module "eks_managed_node_group" {
| <a name="output_node_group_resources"></a> [node\_group\_resources](#output\_node\_group\_resources) | List of objects containing information about underlying resources |
| <a name="output_node_group_status"></a> [node\_group\_status](#output\_node\_group\_status) | Status of the EKS Node Group |
| <a name="output_node_group_taints"></a> [node\_group\_taints](#output\_node\_group\_taints) | List of objects containing information about taints applied to the node group |
| <a name="output_platform"></a> [platform](#output\_platform) | [DEPRECATED - Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023`, or `windows` |
| <a name="output_security_group_arn"></a> [security\_group\_arn](#output\_security\_group\_arn) | Amazon Resource Name (ARN) of the security group |
| <a name="output_security_group_id"></a> [security\_group\_id](#output\_security\_group\_id) | ID of the security group |
<!-- END_TF_DOCS -->
+271 -198
View File
@@ -1,5 +1,14 @@
data "aws_partition" "current" {}
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {
count = var.create && var.partition == "" ? 1 : 0
}
data "aws_caller_identity" "current" {
count = var.create && var.account_id == "" ? 1 : 0
}
locals {
partition = try(data.aws_partition.current[0].partition, var.partition)
account_id = try(data.aws_caller_identity.current[0].account_id, var.account_id)
}
################################################################################
# User Data
@@ -9,14 +18,13 @@ module "user_data" {
source = "../_user_data"
create = var.create
platform = var.platform
ami_type = var.ami_type
cluster_name = var.cluster_name
cluster_endpoint = var.cluster_endpoint
cluster_auth_base64 = var.cluster_auth_base64
cluster_ip_family = var.cluster_ip_family
cluster_service_cidr = try(coalesce(var.cluster_service_cidr, var.cluster_service_ipv4_cidr), "")
cluster_service_cidr = var.cluster_service_cidr
enable_bootstrap_user_data = var.enable_bootstrap_user_data
pre_bootstrap_user_data = var.pre_bootstrap_user_data
@@ -35,6 +43,8 @@ module "user_data" {
data "aws_ec2_instance_type" "this" {
count = var.create && var.enable_efa_support ? 1 : 0
region = var.region
instance_type = local.efa_instance_type
}
@@ -64,71 +74,72 @@ locals {
locals {
launch_template_name = coalesce(var.launch_template_name, "${var.name}-eks-node-group")
security_group_ids = compact(concat([var.cluster_primary_security_group_id], var.vpc_security_group_ids))
placement = local.create_placement_group ? { group_name = aws_placement_group.this[0].name } : var.placement
security_group_ids = compact(concat([var.cluster_primary_security_group_id], var.vpc_security_group_ids, aws_security_group.this[*].id))
}
resource "aws_launch_template" "this" {
count = var.create && var.create_launch_template && var.use_custom_launch_template ? 1 : 0
region = var.region
dynamic "block_device_mappings" {
for_each = var.block_device_mappings
for_each = var.block_device_mappings != null ? var.block_device_mappings : {}
content {
device_name = try(block_device_mappings.value.device_name, null)
device_name = block_device_mappings.value.device_name
dynamic "ebs" {
for_each = try([block_device_mappings.value.ebs], [])
for_each = block_device_mappings.value.ebs != null ? [block_device_mappings.value.ebs] : []
content {
delete_on_termination = try(ebs.value.delete_on_termination, null)
encrypted = try(ebs.value.encrypted, null)
iops = try(ebs.value.iops, null)
kms_key_id = try(ebs.value.kms_key_id, null)
snapshot_id = try(ebs.value.snapshot_id, null)
throughput = try(ebs.value.throughput, null)
volume_size = try(ebs.value.volume_size, null)
volume_type = try(ebs.value.volume_type, null)
delete_on_termination = ebs.value.delete_on_termination
encrypted = ebs.value.encrypted
iops = ebs.value.iops
kms_key_id = ebs.value.kms_key_id
snapshot_id = ebs.value.snapshot_id
throughput = ebs.value.throughput
volume_initialization_rate = ebs.value.volume_initialization_rate
volume_size = ebs.value.volume_size
volume_type = ebs.value.volume_type
}
}
no_device = try(block_device_mappings.value.no_device, null)
virtual_name = try(block_device_mappings.value.virtual_name, null)
no_device = block_device_mappings.value.no_device
virtual_name = block_device_mappings.value.virtual_name
}
}
dynamic "capacity_reservation_specification" {
for_each = length(var.capacity_reservation_specification) > 0 ? [var.capacity_reservation_specification] : []
for_each = var.capacity_reservation_specification != null ? [var.capacity_reservation_specification] : []
content {
capacity_reservation_preference = try(capacity_reservation_specification.value.capacity_reservation_preference, null)
capacity_reservation_preference = capacity_reservation_specification.value.capacity_reservation_preference
dynamic "capacity_reservation_target" {
for_each = try([capacity_reservation_specification.value.capacity_reservation_target], [])
for_each = capacity_reservation_specification.value.capacity_reservation_target != null ? [capacity_reservation_specification.value.capacity_reservation_target] : []
content {
capacity_reservation_id = try(capacity_reservation_target.value.capacity_reservation_id, null)
capacity_reservation_resource_group_arn = try(capacity_reservation_target.value.capacity_reservation_resource_group_arn, null)
capacity_reservation_id = capacity_reservation_target.value.capacity_reservation_id
capacity_reservation_resource_group_arn = capacity_reservation_target.value.capacity_reservation_resource_group_arn
}
}
}
}
dynamic "cpu_options" {
for_each = length(var.cpu_options) > 0 ? [var.cpu_options] : []
for_each = var.cpu_options != null ? [var.cpu_options] : []
content {
core_count = try(cpu_options.value.core_count, null)
threads_per_core = try(cpu_options.value.threads_per_core, null)
amd_sev_snp = cpu_options.value.amd_sev_snp
core_count = cpu_options.value.core_count
threads_per_core = cpu_options.value.threads_per_core
}
}
dynamic "credit_specification" {
for_each = length(var.credit_specification) > 0 ? [var.credit_specification] : []
for_each = var.credit_specification != null ? [var.credit_specification] : []
content {
cpu_credits = try(credit_specification.value.cpu_credits, null)
cpu_credits = credit_specification.value.cpu_credits
}
}
@@ -137,24 +148,8 @@ resource "aws_launch_template" "this" {
disable_api_termination = var.disable_api_termination
ebs_optimized = var.ebs_optimized
dynamic "elastic_gpu_specifications" {
for_each = var.elastic_gpu_specifications
content {
type = elastic_gpu_specifications.value.type
}
}
dynamic "elastic_inference_accelerator" {
for_each = length(var.elastic_inference_accelerator) > 0 ? [var.elastic_inference_accelerator] : []
content {
type = elastic_inference_accelerator.value.type
}
}
dynamic "enclave_options" {
for_each = length(var.enclave_options) > 0 ? [var.enclave_options] : []
for_each = var.enclave_options != null ? [var.enclave_options] : []
content {
enabled = enclave_options.value.enabled
@@ -187,20 +182,20 @@ resource "aws_launch_template" "this" {
# instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior
dynamic "instance_market_options" {
for_each = length(var.instance_market_options) > 0 ? [var.instance_market_options] : []
for_each = var.instance_market_options != null ? [var.instance_market_options] : []
content {
market_type = try(instance_market_options.value.market_type, null)
market_type = instance_market_options.value.market_type
dynamic "spot_options" {
for_each = try([instance_market_options.value.spot_options], [])
for_each = instance_market_options.value.spot_options != null ? [instance_market_options.value.spot_options] : []
content {
block_duration_minutes = try(spot_options.value.block_duration_minutes, null)
instance_interruption_behavior = try(spot_options.value.instance_interruption_behavior, null)
max_price = try(spot_options.value.max_price, null)
spot_instance_type = try(spot_options.value.spot_instance_type, null)
valid_until = try(spot_options.value.valid_until, null)
block_duration_minutes = spot_options.value.block_duration_minutes
instance_interruption_behavior = spot_options.value.instance_interruption_behavior
max_price = spot_options.value.max_price
spot_instance_type = spot_options.value.spot_instance_type
valid_until = spot_options.value.valid_until
}
}
}
@@ -213,7 +208,7 @@ resource "aws_launch_template" "this" {
key_name = var.key_name
dynamic "license_specification" {
for_each = length(var.license_specifications) > 0 ? var.license_specifications : {}
for_each = var.license_specifications != null ? var.license_specifications : []
content {
license_configuration_arn = license_specification.value.license_configuration_arn
@@ -221,22 +216,22 @@ resource "aws_launch_template" "this" {
}
dynamic "maintenance_options" {
for_each = length(var.maintenance_options) > 0 ? [var.maintenance_options] : []
for_each = var.maintenance_options != null ? [var.maintenance_options] : []
content {
auto_recovery = try(maintenance_options.value.auto_recovery, null)
auto_recovery = maintenance_options.value.auto_recovery
}
}
dynamic "metadata_options" {
for_each = length(var.metadata_options) > 0 ? [var.metadata_options] : []
for_each = var.metadata_options != null ? [var.metadata_options] : []
content {
http_endpoint = try(metadata_options.value.http_endpoint, null)
http_protocol_ipv6 = try(metadata_options.value.http_protocol_ipv6, null)
http_put_response_hop_limit = try(metadata_options.value.http_put_response_hop_limit, null)
http_tokens = try(metadata_options.value.http_tokens, null)
instance_metadata_tags = try(metadata_options.value.instance_metadata_tags, null)
http_endpoint = metadata_options.value.http_endpoint
http_protocol_ipv6 = metadata_options.value.http_protocol_ipv6
http_put_response_hop_limit = metadata_options.value.http_put_response_hop_limit
http_tokens = metadata_options.value.http_tokens
instance_metadata_tags = metadata_options.value.instance_metadata_tags
}
}
@@ -252,29 +247,57 @@ resource "aws_launch_template" "this" {
name_prefix = var.launch_template_use_name_prefix ? "${local.launch_template_name}-" : null
dynamic "network_interfaces" {
for_each = local.network_interfaces
for_each = length(var.network_interfaces) > 0 ? var.network_interfaces : []
content {
associate_carrier_ip_address = try(network_interfaces.value.associate_carrier_ip_address, null)
associate_public_ip_address = try(network_interfaces.value.associate_public_ip_address, null)
delete_on_termination = try(network_interfaces.value.delete_on_termination, null)
description = try(network_interfaces.value.description, null)
device_index = try(network_interfaces.value.device_index, null)
interface_type = try(network_interfaces.value.interface_type, null)
ipv4_address_count = try(network_interfaces.value.ipv4_address_count, null)
ipv4_addresses = try(network_interfaces.value.ipv4_addresses, [])
ipv4_prefix_count = try(network_interfaces.value.ipv4_prefix_count, null)
ipv4_prefixes = try(network_interfaces.value.ipv4_prefixes, null)
ipv6_address_count = try(network_interfaces.value.ipv6_address_count, null)
ipv6_addresses = try(network_interfaces.value.ipv6_addresses, [])
ipv6_prefix_count = try(network_interfaces.value.ipv6_prefix_count, null)
ipv6_prefixes = try(network_interfaces.value.ipv6_prefixes, [])
network_card_index = try(network_interfaces.value.network_card_index, null)
network_interface_id = try(network_interfaces.value.network_interface_id, null)
primary_ipv6 = try(network_interfaces.value.primary_ipv6, null)
private_ip_address = try(network_interfaces.value.private_ip_address, null)
associate_carrier_ip_address = network_interfaces.value.associate_carrier_ip_address
associate_public_ip_address = network_interfaces.value.associate_public_ip_address
dynamic "connection_tracking_specification" {
for_each = network_interfaces.value.connection_tracking_specification != null ? [network_interfaces.value.connection_tracking_specification] : []
content {
tcp_established_timeout = connection_tracking_specification.value.tcp_established_timeout
udp_stream_timeout = connection_tracking_specification.value.udp_stream_timeout
udp_timeout = connection_tracking_specification.value.udp_timeout
}
}
delete_on_termination = network_interfaces.value.delete_on_termination
description = network_interfaces.value.description
device_index = network_interfaces.value.device_index
dynamic "ena_srd_specification" {
for_each = network_interfaces.value.ena_srd_specification != null ? [network_interfaces.value.ena_srd_specification] : []
content {
ena_srd_enabled = ena_srd_specification.value.ena_srd_enabled
dynamic "ena_srd_udp_specification" {
for_each = ena_srd_specification.value.ena_srd_udp_specification != null ? [ena_srd_specification.value.ena_srd_udp_specification] : []
content {
ena_srd_udp_enabled = ena_srd_udp_specification.value.ena_srd_udp_enabled
}
}
}
}
interface_type = network_interfaces.value.interface_type
ipv4_address_count = network_interfaces.value.ipv4_address_count
ipv4_addresses = network_interfaces.value.ipv4_addresses
ipv4_prefix_count = network_interfaces.value.ipv4_prefix_count
ipv4_prefixes = network_interfaces.value.ipv4_prefixes
ipv6_address_count = network_interfaces.value.ipv6_address_count
ipv6_addresses = network_interfaces.value.ipv6_addresses
ipv6_prefix_count = network_interfaces.value.ipv6_prefix_count
ipv6_prefixes = network_interfaces.value.ipv6_prefixes
network_card_index = network_interfaces.value.network_card_index
network_interface_id = network_interfaces.value.network_interface_id
primary_ipv6 = network_interfaces.value.primary_ipv6
private_ip_address = network_interfaces.value.private_ip_address
# Ref: https://github.com/hashicorp/terraform-provider-aws/issues/4570
security_groups = compact(concat(try(network_interfaces.value.security_groups, []), local.security_group_ids))
security_groups = compact(concat(network_interfaces.value.security_groups, var.vpc_security_group_ids))
# Set on EKS managed node group, will fail if set here
# https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-basics
# subnet_id = try(network_interfaces.value.subnet_id, null)
@@ -282,14 +305,14 @@ resource "aws_launch_template" "this" {
}
dynamic "placement" {
for_each = length(local.placement) > 0 ? [local.placement] : []
for_each = var.placement != null || local.create_placement_group ? [var.placement] : []
content {
affinity = try(placement.value.affinity, null)
availability_zone = lookup(placement.value, "availability_zone", null)
group_name = lookup(placement.value, "group_name", null)
host_id = lookup(placement.value, "host_id", null)
host_resource_group_arn = lookup(placement.value, "host_resource_group_arn", null)
availability_zone = try(placement.value.availability_zone, null)
group_name = try(aws_placement_group.this[0].name, placement.value.group_name)
host_id = try(placement.value.host_id, null)
host_resource_group_arn = try(placement.value.host_resource_group_arn, null)
partition_number = try(placement.value.partition_number, null)
spread_domain = try(placement.value.spread_domain, null)
tenancy = try(placement.value.tenancy, null)
@@ -297,12 +320,12 @@ resource "aws_launch_template" "this" {
}
dynamic "private_dns_name_options" {
for_each = length(var.private_dns_name_options) > 0 ? [var.private_dns_name_options] : []
for_each = var.private_dns_name_options != null ? [var.private_dns_name_options] : []
content {
enable_resource_name_dns_aaaa_record = try(private_dns_name_options.value.enable_resource_name_dns_aaaa_record, null)
enable_resource_name_dns_a_record = try(private_dns_name_options.value.enable_resource_name_dns_a_record, null)
hostname_type = try(private_dns_name_options.value.hostname_type, null)
enable_resource_name_dns_aaaa_record = private_dns_name_options.value.enable_resource_name_dns_aaaa_record
enable_resource_name_dns_a_record = private_dns_name_options.value.enable_resource_name_dns_a_record
hostname_type = private_dns_name_options.value.hostname_type
}
}
@@ -342,32 +365,41 @@ resource "aws_launch_template" "this" {
# AMI SSM Parameter
################################################################################
data "aws_eks_cluster_versions" "this" {
count = var.create && var.kubernetes_version == null ? 1 : 0
region = var.region
cluster_type = "eks"
version_status = "STANDARD_SUPPORT"
}
locals {
# Just to ensure templating doesn't fail when values are not provided
ssm_cluster_version = var.cluster_version != null ? var.cluster_version : ""
ssm_kubernetes_version = var.kubernetes_version != null ? var.kubernetes_version : try(data.aws_eks_cluster_versions.this[0].cluster_versions[0].cluster_version, "UNSPECIFIED")
ssm_ami_type = var.ami_type != null ? var.ami_type : ""
# Map the AMI type to the respective SSM param path
ssm_ami_type_to_ssm_param = {
AL2_x86_64 = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2/recommended/release_version"
AL2_x86_64_GPU = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2-gpu/recommended/release_version"
AL2_ARM_64 = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2-arm64/recommended/release_version"
AL2_x86_64 = "/aws/service/eks/optimized-ami/${local.ssm_kubernetes_version}/amazon-linux-2/recommended/release_version"
AL2_x86_64_GPU = "/aws/service/eks/optimized-ami/${local.ssm_kubernetes_version}/amazon-linux-2-gpu/recommended/release_version"
AL2_ARM_64 = "/aws/service/eks/optimized-ami/${local.ssm_kubernetes_version}/amazon-linux-2-arm64/recommended/release_version"
CUSTOM = "NONE"
BOTTLEROCKET_ARM_64 = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}/arm64/latest/image_version"
BOTTLEROCKET_x86_64 = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}/x86_64/latest/image_version"
BOTTLEROCKET_ARM_64_FIPS = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}-fips/arm64/latest/image_version"
BOTTLEROCKET_x86_64_FIPS = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}-fips/x86_64/latest/image_version"
BOTTLEROCKET_ARM_64_NVIDIA = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}-nvidia/arm64/latest/image_version"
BOTTLEROCKET_x86_64_NVIDIA = "/aws/service/bottlerocket/aws-k8s-${local.ssm_cluster_version}-nvidia/x86_64/latest/image_version"
WINDOWS_CORE_2019_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-${local.ssm_cluster_version}"
WINDOWS_FULL_2019_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-${local.ssm_cluster_version}"
WINDOWS_CORE_2022_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-EKS_Optimized-${local.ssm_cluster_version}"
WINDOWS_FULL_2022_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2022-English-Core-EKS_Optimized-${local.ssm_cluster_version}"
AL2023_x86_64_STANDARD = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2023/x86_64/standard/recommended/release_version"
AL2023_ARM_64_STANDARD = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2023/arm64/standard/recommended/release_version"
AL2023_x86_64_NEURON = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2023/x86_64/neuron/recommended/release_version"
AL2023_x86_64_NVIDIA = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2023/x86_64/nvidia/recommended/release_version"
AL2023_ARM_64_NVIDIA = "/aws/service/eks/optimized-ami/${local.ssm_cluster_version}/amazon-linux-2023/arm64/nvidia/recommended/release_version"
BOTTLEROCKET_ARM_64 = "/aws/service/bottlerocket/aws-k8s-${local.ssm_kubernetes_version}/arm64/latest/image_version"
BOTTLEROCKET_x86_64 = "/aws/service/bottlerocket/aws-k8s-${local.ssm_kubernetes_version}/x86_64/latest/image_version"
BOTTLEROCKET_ARM_64_FIPS = "/aws/service/bottlerocket/aws-k8s-${local.ssm_kubernetes_version}-fips/arm64/latest/image_version"
BOTTLEROCKET_x86_64_FIPS = "/aws/service/bottlerocket/aws-k8s-${local.ssm_kubernetes_version}-fips/x86_64/latest/image_version"
BOTTLEROCKET_ARM_64_NVIDIA = "/aws/service/bottlerocket/aws-k8s-${local.ssm_kubernetes_version}-nvidia/arm64/latest/image_version"
BOTTLEROCKET_x86_64_NVIDIA = "/aws/service/bottlerocket/aws-k8s-${local.ssm_kubernetes_version}-nvidia/x86_64/latest/image_version"
WINDOWS_CORE_2019_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-EKS_Optimized-${local.ssm_kubernetes_version}"
WINDOWS_FULL_2019_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-${local.ssm_kubernetes_version}"
WINDOWS_CORE_2022_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-EKS_Optimized-${local.ssm_kubernetes_version}"
WINDOWS_FULL_2022_x86_64 = "/aws/service/ami-windows-latest/Windows_Server-2022-English-Core-EKS_Optimized-${local.ssm_kubernetes_version}"
AL2023_x86_64_STANDARD = "/aws/service/eks/optimized-ami/${local.ssm_kubernetes_version}/amazon-linux-2023/x86_64/standard/recommended/release_version"
AL2023_ARM_64_STANDARD = "/aws/service/eks/optimized-ami/${local.ssm_kubernetes_version}/amazon-linux-2023/arm64/standard/recommended/release_version"
AL2023_x86_64_NEURON = "/aws/service/eks/optimized-ami/${local.ssm_kubernetes_version}/amazon-linux-2023/x86_64/neuron/recommended/release_version"
AL2023_x86_64_NVIDIA = "/aws/service/eks/optimized-ami/${local.ssm_kubernetes_version}/amazon-linux-2023/x86_64/nvidia/recommended/release_version"
AL2023_ARM_64_NVIDIA = "/aws/service/eks/optimized-ami/${local.ssm_kubernetes_version}/amazon-linux-2023/arm64/nvidia/recommended/release_version"
}
# The Windows SSM params currently do not have a release version, so we have to get the full output JSON blob and parse out the release version
@@ -379,6 +411,8 @@ locals {
data "aws_ssm_parameter" "ami" {
count = var.create && var.use_latest_ami_release_version ? 1 : 0
region = var.region
name = local.ssm_ami_type_to_ssm_param[var.ami_type]
}
@@ -395,10 +429,12 @@ locals {
resource "aws_eks_node_group" "this" {
count = var.create ? 1 : 0
region = var.region
# Required
cluster_name = var.cluster_name
node_role_arn = var.create_iam_role ? aws_iam_role.this[0].arn : var.iam_role_arn
subnet_ids = local.create_placement_group ? data.aws_subnets.placement_group[0].ids : var.subnet_ids
subnet_ids = var.subnet_ids
scaling_config {
min_size = var.min_size
@@ -413,7 +449,7 @@ resource "aws_eks_node_group" "this" {
# https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html#launch-template-custom-ami
ami_type = var.ami_id != "" ? null : var.ami_type
release_version = var.ami_id != "" ? null : var.use_latest_ami_release_version ? local.latest_ami_release_version : var.ami_release_version
version = var.ami_id != "" ? null : var.cluster_version
version = var.ami_id != "" ? null : var.kubernetes_version
capacity_type = var.capacity_type
disk_size = var.use_custom_launch_template ? null : var.disk_size # if using a custom LT, set disk size on custom LT or else it will error here
@@ -432,30 +468,30 @@ resource "aws_eks_node_group" "this" {
}
dynamic "remote_access" {
for_each = length(var.remote_access) > 0 ? [var.remote_access] : []
for_each = var.remote_access != null ? [var.remote_access] : []
content {
ec2_ssh_key = try(remote_access.value.ec2_ssh_key, null)
source_security_group_ids = try(remote_access.value.source_security_group_ids, [])
ec2_ssh_key = remote_access.value.ec2_ssh_key
source_security_group_ids = remote_access.value.source_security_group_ids
}
}
dynamic "taint" {
for_each = var.taints
for_each = var.taints != null ? var.taints : {}
content {
key = taint.value.key
value = try(taint.value.value, null)
value = taint.value.value
effect = taint.value.effect
}
}
dynamic "update_config" {
for_each = length(var.update_config) > 0 ? [var.update_config] : []
for_each = var.update_config != null ? [var.update_config] : []
content {
max_unavailable_percentage = try(update_config.value.max_unavailable_percentage, null)
max_unavailable = try(update_config.value.max_unavailable, null)
max_unavailable_percentage = update_config.value.max_unavailable_percentage
max_unavailable = update_config.value.max_unavailable
}
}
@@ -467,10 +503,14 @@ resource "aws_eks_node_group" "this" {
}
}
timeouts {
create = lookup(var.timeouts, "create", null)
update = lookup(var.timeouts, "update", null)
delete = lookup(var.timeouts, "delete", null)
dynamic "timeouts" {
for_each = var.timeouts != null ? [var.timeouts] : []
content {
create = var.timeouts.create
update = var.timeouts.update
delete = var.timeouts.delete
}
}
lifecycle {
@@ -494,13 +534,13 @@ locals {
create_iam_role = var.create && var.create_iam_role
iam_role_name = coalesce(var.iam_role_name, "${var.name}-eks-node-group")
iam_role_policy_prefix = "arn:${data.aws_partition.current.partition}:iam::aws:policy"
iam_role_policy_prefix = "arn:${local.partition}:iam::aws:policy"
ipv4_cni_policy = { for k, v in {
AmazonEKS_CNI_Policy = "${local.iam_role_policy_prefix}/AmazonEKS_CNI_Policy"
} : k => v if var.iam_role_attach_cni_policy && var.cluster_ip_family == "ipv4" }
ipv6_cni_policy = { for k, v in {
AmazonEKS_CNI_IPv6_Policy = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/AmazonEKS_CNI_IPv6_Policy"
AmazonEKS_CNI_IPv6_Policy = "arn:${local.partition}:iam::${local.account_id}:policy/AmazonEKS_CNI_IPv6_Policy"
} : k => v if var.iam_role_attach_cni_policy && var.cluster_ip_family == "ipv6" }
}
@@ -560,25 +600,25 @@ resource "aws_iam_role_policy_attachment" "additional" {
################################################################################
locals {
create_iam_role_policy = local.create_iam_role && var.create_iam_role_policy && length(var.iam_role_policy_statements) > 0
create_iam_role_policy = local.create_iam_role && var.create_iam_role_policy && var.iam_role_policy_statements != null
}
data "aws_iam_policy_document" "role" {
count = local.create_iam_role_policy ? 1 : 0
dynamic "statement" {
for_each = var.iam_role_policy_statements
for_each = var.iam_role_policy_statements != null ? var.iam_role_policy_statements : []
content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)
sid = statement.value.sid
actions = statement.value.actions
not_actions = statement.value.not_actions
effect = statement.value.effect
resources = statement.value.resources
not_resources = statement.value.not_resources
dynamic "principals" {
for_each = try(statement.value.principals, [])
for_each = statement.value.principals != null ? statement.value.principals : []
content {
type = principals.value.type
@@ -587,7 +627,7 @@ data "aws_iam_policy_document" "role" {
}
dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])
for_each = statement.value.not_principals != null ? statement.value.not_principals : []
content {
type = not_principals.value.type
@@ -596,7 +636,7 @@ data "aws_iam_policy_document" "role" {
}
dynamic "condition" {
for_each = try(statement.value.conditions, [])
for_each = statement.value.condition != null ? statement.value.condition : []
content {
test = condition.value.test
@@ -628,84 +668,117 @@ locals {
resource "aws_placement_group" "this" {
count = local.create_placement_group ? 1 : 0
region = var.region
name = "${var.cluster_name}-${var.name}"
strategy = var.placement_group_strategy
strategy = "cluster"
tags = var.tags
}
################################################################################
# Instance AZ Lookup
# Instances usually used in placement groups w/ EFA are only available in
# select availability zones. These data sources will cross reference the availability
# zones supported by the instance type with the subnets provided to ensure only
# AZs/subnets that are supported are used.
# Security Group
################################################################################
# Find the availability zones supported by the instance type
# TODO - remove at next breaking change
# Force users to be explicit about which AZ to use when using placement groups,
# with or without EFA support
data "aws_ec2_instance_type_offerings" "this" {
count = local.enable_efa_support ? 1 : 0
locals {
create_security_group = var.create && var.create_security_group && length(merge(local.security_group_ingress_rules, local.security_group_egress_rules)) > 0
security_group_name = coalesce(var.security_group_name, "${var.cluster_name}-${var.name}")
filter {
name = "instance-type"
values = [local.efa_instance_type]
security_group_ingress_rules = merge({ for k, v in
{
all_self_efa = {
description = "Node to node EFA"
protocol = "-1"
from_port = 0
self = true
}
location_type = "availability-zone-id"
} : k => v if var.enable_efa_support
},
var.security_group_ingress_rules
)
security_group_egress_rules = merge({ for k, v in
{
all_self_efa = {
description = "Node to node EFA"
protocol = "-1"
to_port = 0
self = true
}
} : k => v if var.enable_efa_support
},
var.security_group_egress_rules
)
}
# Reverse the lookup to find one of the subnets provided based on the availability
# availability zone ID of the queried instance type (supported)
data "aws_subnets" "placement_group" {
count = local.create_placement_group ? 1 : 0
data "aws_subnet" "this" {
count = local.create_security_group ? 1 : 0
filter {
name = "subnet-id"
values = var.subnet_ids
}
region = var.region
# The data source can lookup the first available AZ or you can specify an AZ (next filter)
dynamic "filter" {
for_each = var.enable_efa_support && var.placement_group_az == null ? [1] : []
id = element(var.subnet_ids, 0)
}
content {
name = "availability-zone-id"
values = data.aws_ec2_instance_type_offerings.this[0].locations
}
}
resource "aws_security_group" "this" {
count = local.create_security_group ? 1 : 0
dynamic "filter" {
for_each = var.placement_group_az != null ? [var.placement_group_az] : []
region = var.region
content {
name = "availability-zone"
values = [filter.value]
}
name = var.security_group_use_name_prefix ? null : local.security_group_name
name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null
description = var.security_group_description
vpc_id = data.aws_subnet.this[0].vpc_id
tags = merge(
var.tags,
{ "Name" = local.security_group_name },
var.security_group_tags
)
lifecycle {
create_before_destroy = true
}
}
################################################################################
# Autoscaling Group Schedule
################################################################################
resource "aws_vpc_security_group_ingress_rule" "this" {
for_each = { for k, v in local.security_group_ingress_rules : k => v if length(local.security_group_ingress_rules) > 0 && local.create_security_group }
resource "aws_autoscaling_schedule" "this" {
for_each = { for k, v in var.schedules : k => v if var.create && var.create_schedule }
region = var.region
scheduled_action_name = each.key
autoscaling_group_name = aws_eks_node_group.this[0].resources[0].autoscaling_groups[0].name
min_size = try(each.value.min_size, -1)
max_size = try(each.value.max_size, -1)
desired_capacity = try(each.value.desired_size, -1)
start_time = try(each.value.start_time, null)
end_time = try(each.value.end_time, null)
time_zone = try(each.value.time_zone, null)
# [Minute] [Hour] [Day_of_Month] [Month_of_Year] [Day_of_Week]
# Cron examples: https://crontab.guru/examples.html
recurrence = try(each.value.recurrence, null)
cidr_ipv4 = each.value.cidr_ipv4
cidr_ipv6 = each.value.cidr_ipv6
description = each.value.description
from_port = each.value.from_port
ip_protocol = each.value.ip_protocol
prefix_list_id = each.value.prefix_list_id
referenced_security_group_id = each.value.self ? aws_security_group.this[0].id : each.value.referenced_security_group_id
security_group_id = aws_security_group.this[0].id
tags = merge(
var.tags,
var.security_group_tags,
{ "Name" = coalesce(each.value.name, "${local.security_group_name}-${each.key}") },
each.value.tags
)
to_port = try(coalesce(each.value.to_port, each.value.from_port), null)
}
resource "aws_vpc_security_group_egress_rule" "this" {
for_each = { for k, v in local.security_group_egress_rules : k => v if length(local.security_group_egress_rules) > 0 && local.create_security_group }
region = var.region
cidr_ipv4 = each.value.cidr_ipv4
cidr_ipv6 = each.value.cidr_ipv6
description = each.value.description
from_port = try(coalesce(each.value.from_port, each.value.to_port), null)
ip_protocol = each.value.ip_protocol
prefix_list_id = each.value.prefix_list_id
referenced_security_group_id = each.value.self ? aws_security_group.this[0].id : each.value.referenced_security_group_id
security_group_id = aws_security_group.this[0].id
tags = merge(
var.tags,
var.security_group_tags,
{ "Name" = coalesce(each.value.name, "${local.security_group_name}-${each.key}") },
each.value.tags
)
to_port = each.value.to_port
}
+9 -13
View File
@@ -61,15 +61,6 @@ output "node_group_taints" {
value = try(aws_eks_node_group.this[0].taint, [])
}
################################################################################
# Autoscaling Group Schedule
################################################################################
output "autoscaling_group_schedule_arns" {
description = "ARNs of autoscaling group schedules"
value = { for k, v in aws_autoscaling_schedule.this : k => v.arn }
}
################################################################################
# IAM Role
################################################################################
@@ -90,10 +81,15 @@ output "iam_role_unique_id" {
}
################################################################################
# Additional
# Security Group
################################################################################
output "platform" {
description = "[DEPRECATED - Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023`, or `windows`"
value = module.user_data.platform
output "security_group_arn" {
description = "Amazon Resource Name (ARN) of the security group"
value = try(aws_security_group.this[0].arn, null)
}
output "security_group_id" {
description = "ID of the security group"
value = try(aws_security_group.this[0].id, null)
}
+287 -93
View File
@@ -2,6 +2,7 @@ variable "create" {
description = "Determines whether to create EKS managed node group or not"
type = bool
default = true
nullable = false
}
variable "tags" {
@@ -10,10 +11,22 @@ variable "tags" {
default = {}
}
variable "platform" {
description = "[DEPRECATED - use `ami_type` instead. Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023`, or `windows`"
variable "region" {
description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration"
type = string
default = "linux"
default = null
}
variable "partition" {
description = "The AWS partition - pass through value to reduce number of GET requests from data sources"
type = string
default = ""
}
variable "account_id" {
description = "The AWS account ID - pass through value to reduce number of GET requests from data sources"
type = string
default = ""
}
################################################################################
@@ -24,61 +37,55 @@ variable "enable_bootstrap_user_data" {
description = "Determines whether the bootstrap configurations are populated within the user data template. Only valid when using a custom AMI via `ami_id`"
type = bool
default = false
nullable = false
}
variable "cluster_name" {
description = "Name of associated EKS cluster"
type = string
default = null
default = ""
}
variable "cluster_endpoint" {
description = "Endpoint of associated EKS cluster"
type = string
default = ""
default = null
}
variable "cluster_auth_base64" {
description = "Base64 encoded CA of associated EKS cluster"
type = string
default = ""
default = null
}
variable "cluster_service_cidr" {
description = "The CIDR block (IPv4 or IPv6) used by the cluster to assign Kubernetes service IP addresses. This is derived from the cluster itself"
type = string
default = ""
}
# TODO - remove at next breaking change
variable "cluster_service_ipv4_cidr" {
description = "[Deprecated] The CIDR block to assign Kubernetes service IP addresses from. If you don't specify a block, Kubernetes assigns addresses from either the 10.100.0.0/16 or 172.20.0.0/16 CIDR blocks"
type = string
default = null
}
variable "pre_bootstrap_user_data" {
description = "User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*`"
type = string
default = ""
default = null
}
variable "post_bootstrap_user_data" {
description = "User data that is appended to the user data script after of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*`"
type = string
default = ""
default = null
}
variable "bootstrap_extra_args" {
description = "Additional arguments passed to the bootstrap script. When `ami_type` = `BOTTLEROCKET_*`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data"
type = string
default = ""
default = null
}
variable "user_data_template_path" {
description = "Path to a local, custom user data template file to use when rendering user data"
type = string
default = ""
default = null
}
variable "cloudinit_pre_nodeadm" {
@@ -89,7 +96,7 @@ variable "cloudinit_pre_nodeadm" {
filename = optional(string)
merge_type = optional(string)
}))
default = []
default = null
}
variable "cloudinit_post_nodeadm" {
@@ -100,7 +107,7 @@ variable "cloudinit_post_nodeadm" {
filename = optional(string)
merge_type = optional(string)
}))
default = []
default = null
}
################################################################################
@@ -111,12 +118,14 @@ variable "create_launch_template" {
description = "Determines whether to create a launch template or not. If set to `false`, EKS will use its own default launch template"
type = bool
default = true
nullable = false
}
variable "use_custom_launch_template" {
description = "Determines whether to use a custom launch template or not. If set to `false`, EKS will use its own default launch template"
type = bool
default = true
nullable = false
}
variable "launch_template_id" {
@@ -135,6 +144,7 @@ variable "launch_template_use_name_prefix" {
description = "Determines whether to use `launch_template_name` as is or create a unique name beginning with the `launch_template_name` as the prefix"
type = bool
default = true
nullable = false
}
variable "launch_template_description" {
@@ -165,6 +175,7 @@ variable "vpc_security_group_ids" {
description = "A list of security group IDs to associate"
type = list(string)
default = []
nullable = false
}
variable "cluster_primary_security_group_id" {
@@ -183,6 +194,7 @@ variable "update_launch_template_default_version" {
description = "Whether to update the launch templates default version on each update. Conflicts with `launch_template_default_version`"
type = bool
default = true
nullable = false
}
variable "disable_api_termination" {
@@ -205,129 +217,208 @@ variable "ram_disk_id" {
variable "block_device_mappings" {
description = "Specify volumes to attach to the instance besides the volumes specified by the AMI"
type = any
default = {}
type = map(object({
device_name = optional(string)
ebs = optional(object({
delete_on_termination = optional(bool)
encrypted = optional(bool)
iops = optional(number)
kms_key_id = optional(string)
snapshot_id = optional(string)
throughput = optional(number)
volume_initialization_rate = optional(number)
volume_size = optional(number)
volume_type = optional(string)
}))
no_device = optional(string)
virtual_name = optional(string)
}))
default = null
}
variable "capacity_reservation_specification" {
description = "Targeting for EC2 capacity reservations"
type = any
default = {}
type = object({
capacity_reservation_preference = optional(string)
capacity_reservation_target = optional(object({
capacity_reservation_id = optional(string)
capacity_reservation_resource_group_arn = optional(string)
}))
})
default = null
}
variable "cpu_options" {
description = "The CPU options for the instance"
type = map(string)
default = {}
type = object({
amd_sev_snp = optional(string)
core_count = optional(number)
threads_per_core = optional(number)
})
default = null
}
variable "credit_specification" {
description = "Customize the credit specification of the instance"
type = map(string)
default = {}
}
variable "elastic_gpu_specifications" {
description = "The elastic GPU to attach to the instance"
type = any
default = {}
}
variable "elastic_inference_accelerator" {
description = "Configuration block containing an Elastic Inference Accelerator to attach to the instance"
type = map(string)
default = {}
type = object({
cpu_credits = optional(string)
})
default = null
}
variable "enclave_options" {
description = "Enable Nitro Enclaves on launched instances"
type = map(string)
default = {}
type = object({
enabled = optional(bool)
})
default = null
}
variable "instance_market_options" {
description = "The market (purchasing) option for the instance"
type = any
default = {}
type = object({
market_type = optional(string)
spot_options = optional(object({
block_duration_minutes = optional(number)
instance_interruption_behavior = optional(string)
max_price = optional(string)
spot_instance_type = optional(string)
valid_until = optional(string)
}))
})
default = null
}
variable "maintenance_options" {
description = "The maintenance options for the instance"
type = any
default = {}
type = object({
auto_recovery = optional(string)
})
default = null
}
variable "license_specifications" {
description = "A map of license specifications to associate with"
type = any
default = {}
description = "A list of license specifications to associate with"
type = list(object({
license_configuration_arn = string
}))
default = null
}
variable "metadata_options" {
description = "Customize the metadata options for the instance"
type = map(string)
type = object({
http_endpoint = optional(string, "enabled")
http_protocol_ipv6 = optional(string)
http_put_response_hop_limit = optional(number, 1)
http_tokens = optional(string, "required")
instance_metadata_tags = optional(string)
})
default = {
http_endpoint = "enabled"
http_put_response_hop_limit = 1
http_tokens = "required"
http_put_response_hop_limit = 2
}
nullable = false
}
# TODO - make this false by default at next breaking change
variable "enable_monitoring" {
description = "Enables/disables detailed monitoring"
type = bool
default = true
default = false
nullable = false
}
variable "enable_efa_support" {
description = "Determines whether to enable Elastic Fabric Adapter (EFA) support"
type = bool
default = false
nullable = false
}
# TODO - make this true by default at next breaking change (remove variable, only pass indices)
variable "enable_efa_only" {
description = "Determines whether to enable EFA (`false`, default) or EFA and EFA-only (`true`) network interfaces. Note: requires vpc-cni version `v1.18.4` or later"
type = bool
default = false
default = true
nullable = false
}
variable "efa_indices" {
description = "The indices of the network interfaces that should be EFA-enabled. Only valid when `enable_efa_support` = `true`"
type = list(number)
default = [0]
nullable = false
}
variable "network_interfaces" {
description = "Customize network interfaces to be attached at instance boot time"
type = list(any)
type = list(object({
associate_carrier_ip_address = optional(bool)
associate_public_ip_address = optional(bool)
connection_tracking_specification = optional(object({
tcp_established_timeout = optional(number)
udp_stream_timeout = optional(number)
udp_timeout = optional(number)
}))
delete_on_termination = optional(bool)
description = optional(string)
device_index = optional(number)
ena_srd_specification = optional(object({
ena_srd_enabled = optional(bool)
ena_srd_udp_specification = optional(object({
ena_srd_udp_enabled = optional(bool)
}))
}))
interface_type = optional(string)
ipv4_address_count = optional(number)
ipv4_addresses = optional(list(string))
ipv4_prefix_count = optional(number)
ipv4_prefixes = optional(list(string))
ipv6_address_count = optional(number)
ipv6_addresses = optional(list(string))
ipv6_prefix_count = optional(number)
ipv6_prefixes = optional(list(string))
network_card_index = optional(number)
network_interface_id = optional(string)
primary_ipv6 = optional(bool)
private_ip_address = optional(string)
security_groups = optional(list(string), [])
subnet_id = optional(string)
}))
default = []
nullable = false
}
variable "placement" {
description = "The placement of the instance"
type = map(string)
default = {}
type = object({
affinity = optional(string)
availability_zone = optional(string)
group_name = optional(string)
host_id = optional(string)
host_resource_group_arn = optional(string)
partition_number = optional(number)
spread_domain = optional(string)
tenancy = optional(string)
})
default = null
}
variable "create_placement_group" {
description = "Determines whether a placement group is created & used by the node group"
type = bool
default = false
}
# TODO - remove at next breaking change
variable "placement_group_strategy" {
description = "The placement group strategy"
type = string
default = "cluster"
nullable = false
}
variable "private_dns_name_options" {
description = "The options for the instance hostname. The default values are inherited from the subnet"
type = map(string)
default = {}
type = object({
enable_resource_name_dns_aaaa_record = optional(bool)
enable_resource_name_dns_a_record = optional(bool)
hostname_type = optional(string)
})
default = null
}
variable "launch_template_tags" {
@@ -340,6 +431,7 @@ variable "tag_specifications" {
description = "The tags to apply to the resources during launch"
type = list(string)
default = ["instance", "volume", "network-interface"]
nullable = false
}
################################################################################
@@ -352,28 +444,25 @@ variable "subnet_ids" {
default = null
}
variable "placement_group_az" {
description = "Availability zone where placement group is created (ex. `eu-west-1c`)"
type = string
default = null
}
variable "min_size" {
description = "Minimum number of instances/nodes"
type = number
default = 0
default = 1
nullable = false
}
variable "max_size" {
description = "Maximum number of instances/nodes"
type = number
default = 3
nullable = false
}
variable "desired_size" {
description = "Desired number of instances/nodes"
type = number
default = 1
nullable = false
}
variable "name" {
@@ -386,12 +475,14 @@ variable "use_name_prefix" {
description = "Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix"
type = bool
default = true
nullable = false
}
variable "ami_type" {
description = "Type of Amazon Machine Image (AMI) associated with the EKS Node Group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values"
type = string
default = null
default = "AL2023_x86_64_STANDARD"
nullable = false
}
variable "ami_release_version" {
@@ -401,15 +492,17 @@ variable "ami_release_version" {
}
variable "use_latest_ami_release_version" {
description = "Determines whether to use the latest AMI release version for the given `ami_type` (except for `CUSTOM`). Note: `ami_type` and `cluster_version` must be supplied in order to enable this feature"
description = "Determines whether to use the latest AMI release version for the given `ami_type` (except for `CUSTOM`). Note: `ami_type` and `kubernetes_version` must be supplied in order to enable this feature"
type = bool
default = false
default = true
nullable = false
}
variable "capacity_type" {
description = "Type of capacity associated with the EKS Node Group. Valid values: `ON_DEMAND`, `SPOT`"
type = string
default = "ON_DEMAND"
nullable = false
}
variable "disk_size" {
@@ -436,7 +529,7 @@ variable "labels" {
default = null
}
variable "cluster_version" {
variable "kubernetes_version" {
description = "Kubernetes version. Defaults to EKS Cluster Kubernetes version"
type = string
default = null
@@ -450,22 +543,33 @@ variable "launch_template_version" {
variable "remote_access" {
description = "Configuration block with remote access settings. Only valid when `use_custom_launch_template` = `false`"
type = any
default = {}
type = object({
ec2_ssh_key = optional(string)
source_security_group_ids = optional(list(string))
})
default = null
}
variable "taints" {
description = "The Kubernetes taints to be applied to the nodes in the node group. Maximum of 50 taints per node group"
type = any
default = {}
type = map(object({
key = string
value = optional(string)
effect = string
}))
default = null
}
variable "update_config" {
description = "Configuration block of settings for max unavailable resources during node group updates"
type = map(string)
type = object({
max_unavailable = optional(number)
max_unavailable_percentage = optional(number)
})
default = {
max_unavailable_percentage = 33
}
nullable = false
}
variable "node_repair_config" {
@@ -478,8 +582,12 @@ variable "node_repair_config" {
variable "timeouts" {
description = "Create, update, and delete timeout configurations for the node group"
type = map(string)
default = {}
type = object({
create = optional(string)
update = optional(string)
delete = optional(string)
})
default = null
}
################################################################################
@@ -490,12 +598,14 @@ variable "create_iam_role" {
description = "Determines whether an IAM role is created or to use an existing IAM role"
type = bool
default = true
nullable = false
}
variable "cluster_ip_family" {
description = "The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6`"
type = string
default = "ipv4"
nullable = false
}
variable "iam_role_arn" {
@@ -514,6 +624,7 @@ variable "iam_role_use_name_prefix" {
description = "Determines whether the IAM role name (`iam_role_name`) is used as a prefix"
type = bool
default = true
nullable = false
}
variable "iam_role_path" {
@@ -525,7 +636,8 @@ variable "iam_role_path" {
variable "iam_role_description" {
description = "Description of the role"
type = string
default = null
default = "EKS managed node group IAM role"
nullable = false
}
variable "iam_role_permissions_boundary" {
@@ -538,18 +650,21 @@ variable "iam_role_attach_cni_policy" {
description = "Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster"
type = bool
default = true
nullable = false
}
variable "iam_role_additional_policies" {
description = "Additional policies to be added to the IAM role"
type = map(string)
default = {}
nullable = false
}
variable "iam_role_tags" {
description = "A map of additional tags to add to the IAM role created"
type = map(string)
default = {}
nullable = false
}
################################################################################
@@ -560,26 +675,105 @@ variable "create_iam_role_policy" {
description = "Determines whether an IAM role policy is created or not"
type = bool
default = true
nullable = false
}
variable "iam_role_policy_statements" {
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
type = any
default = []
type = list(object({
sid = optional(string)
actions = optional(list(string))
not_actions = optional(list(string))
effect = optional(string)
resources = optional(list(string))
not_resources = optional(list(string))
principals = optional(list(object({
type = string
identifiers = list(string)
})))
not_principals = optional(list(object({
type = string
identifiers = list(string)
})))
condition = optional(list(object({
test = string
values = list(string)
variable = string
})))
}))
default = null
}
################################################################################
# Autoscaling Group Schedule
# Security Group
################################################################################
variable "create_schedule" {
description = "Determines whether to create autoscaling group schedule or not"
variable "create_security_group" {
description = "Determines if a security group is created"
type = bool
default = true
nullable = false
}
variable "schedules" {
description = "Map of autoscaling group schedule to create"
type = map(any)
variable "security_group_name" {
description = "Name to use on security group created"
type = string
default = null
}
variable "security_group_use_name_prefix" {
description = "Determines whether the security group name (`security_group_name`) is used as a prefix"
type = bool
default = true
nullable = false
}
variable "security_group_description" {
description = "Description of the security group created"
type = string
default = null
}
variable "security_group_ingress_rules" {
description = "Security group ingress rules to add to the security group created"
type = map(object({
name = optional(string)
cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(string)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
self = optional(bool, false)
tags = optional(map(string), {})
to_port = optional(string)
}))
default = {}
}
variable "security_group_egress_rules" {
description = "Security group egress rules to add to the security group created"
type = map(object({
name = optional(string)
cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(string)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
self = optional(bool, false)
tags = optional(map(string), {})
to_port = optional(string)
}))
default = {}
}
variable "security_group_tags" {
description = "A map of additional tags to add to the security group created"
type = map(string)
default = {}
}
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+11 -8
View File
@@ -28,14 +28,14 @@ module "fargate_profile" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -60,26 +60,29 @@ No modules.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_account_id"></a> [account\_id](#input\_account\_id) | The AWS account ID - pass through value to reduce number of GET requests from data sources | `string` | `""` | no |
| <a name="input_cluster_ip_family"></a> [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6` | `string` | `"ipv4"` | no |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | `null` | no |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | `""` | no |
| <a name="input_create"></a> [create](#input\_create) | Determines whether to create Fargate profile or not | `bool` | `true` | no |
| <a name="input_create_iam_role"></a> [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created or to use an existing IAM role | `bool` | `true` | no |
| <a name="input_create_iam_role_policy"></a> [create\_iam\_role\_policy](#input\_create\_iam\_role\_policy) | Determines whether an IAM role policy is created or not | `bool` | `true` | no |
| <a name="input_iam_role_additional_policies"></a> [iam\_role\_additional\_policies](#input\_iam\_role\_additional\_policies) | Additional policies to be added to the IAM role | `map(string)` | `{}` | no |
| <a name="input_iam_role_arn"></a> [iam\_role\_arn](#input\_iam\_role\_arn) | Existing IAM role ARN for the Fargate profile. Required if `create_iam_role` is set to `false` | `string` | `null` | no |
| <a name="input_iam_role_attach_cni_policy"></a> [iam\_role\_attach\_cni\_policy](#input\_iam\_role\_attach\_cni\_policy) | Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster | `bool` | `true` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `"Fargate profile IAM role"` | no |
| <a name="input_iam_role_name"></a> [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `""` | no |
| <a name="input_iam_role_path"></a> [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no |
| <a name="input_iam_role_permissions_boundary"></a> [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no |
| <a name="input_iam_role_policy_statements"></a> [iam\_role\_policy\_statements](#input\_iam\_role\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
| <a name="input_iam_role_policy_statements"></a> [iam\_role\_policy\_statements](#input\_iam\_role\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | <pre>list(object({<br/> sid = optional(string)<br/> actions = optional(list(string))<br/> not_actions = optional(list(string))<br/> effect = optional(string)<br/> resources = optional(list(string))<br/> not_resources = optional(list(string))<br/> principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> not_principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> condition = optional(list(object({<br/> test = string<br/> values = list(string)<br/> variable = string<br/> })))<br/> }))</pre> | `null` | no |
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role created | `map(string)` | `{}` | no |
| <a name="input_iam_role_use_name_prefix"></a> [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the IAM role name (`iam_role_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_name"></a> [name](#input\_name) | Name of the EKS Fargate Profile | `string` | `""` | no |
| <a name="input_selectors"></a> [selectors](#input\_selectors) | Configuration block(s) for selecting Kubernetes Pods to execute with this Fargate Profile | `any` | `[]` | no |
| <a name="input_partition"></a> [partition](#input\_partition) | The AWS partition - pass through value to reduce number of GET requests from data sources | `string` | `""` | no |
| <a name="input_region"></a> [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no |
| <a name="input_selectors"></a> [selectors](#input\_selectors) | Configuration block(s) for selecting Kubernetes Pods to execute with this Fargate Profile | <pre>list(object({<br/> labels = optional(map(string))<br/> namespace = string<br/> }))</pre> | `null` | no |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs for the EKS Fargate Profile | `list(string)` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
| <a name="input_timeouts"></a> [timeouts](#input\_timeouts) | Create and delete timeout configurations for the Fargate Profile | `map(string)` | `{}` | no |
| <a name="input_timeouts"></a> [timeouts](#input\_timeouts) | Create and delete timeout configurations for the Fargate Profile | <pre>object({<br/> create = optional(string)<br/> delete = optional(string)<br/> })</pre> | `null` | no |
## Outputs
+39 -22
View File
@@ -1,18 +1,32 @@
data "aws_partition" "current" {}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
data "aws_region" "current" {
count = var.create ? 1 : 0
region = var.region
}
data "aws_partition" "current" {
count = var.create && var.partition == "" ? 1 : 0
}
data "aws_caller_identity" "current" {
count = var.create && var.account_id == "" ? 1 : 0
}
locals {
account_id = try(data.aws_caller_identity.current[0].account_id, var.account_id)
partition = try(data.aws_partition.current[0].partition, var.partition)
region = try(data.aws_region.current[0].region, "")
}
locals {
create_iam_role = var.create && var.create_iam_role
iam_role_name = coalesce(var.iam_role_name, var.name, "fargate-profile")
iam_role_policy_prefix = "arn:${data.aws_partition.current.partition}:iam::aws:policy"
iam_role_policy_prefix = "arn:${local.partition}:iam::aws:policy"
ipv4_cni_policy = { for k, v in {
AmazonEKS_CNI_Policy = "${local.iam_role_policy_prefix}/AmazonEKS_CNI_Policy"
} : k => v if var.iam_role_attach_cni_policy && var.cluster_ip_family == "ipv4" }
ipv6_cni_policy = { for k, v in {
AmazonEKS_CNI_IPv6_Policy = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/AmazonEKS_CNI_IPv6_Policy"
AmazonEKS_CNI_IPv6_Policy = "arn:${local.partition}:iam::${local.account_id}:policy/AmazonEKS_CNI_IPv6_Policy"
} : k => v if var.iam_role_attach_cni_policy && var.cluster_ip_family == "ipv6" }
}
@@ -37,7 +51,7 @@ data "aws_iam_policy_document" "assume_role_policy" {
variable = "aws:SourceArn"
values = [
"arn:${data.aws_partition.current.partition}:eks:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:fargateprofile/${var.cluster_name}/*",
"arn:${local.partition}:eks:${local.region}:${local.account_id}:fargateprofile/${var.cluster_name}/*",
]
}
}
@@ -83,25 +97,25 @@ resource "aws_iam_role_policy_attachment" "additional" {
################################################################################
locals {
create_iam_role_policy = local.create_iam_role && var.create_iam_role_policy && length(var.iam_role_policy_statements) > 0
create_iam_role_policy = local.create_iam_role && var.create_iam_role_policy && var.iam_role_policy_statements != null
}
data "aws_iam_policy_document" "role" {
count = local.create_iam_role_policy ? 1 : 0
dynamic "statement" {
for_each = var.iam_role_policy_statements
for_each = var.iam_role_policy_statements != null ? var.iam_role_policy_statements : []
content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)
sid = statement.value.sid
actions = statement.value.actions
not_actions = statement.value.not_actions
effect = statement.value.effect
resources = statement.value.resources
not_resources = statement.value.not_resources
dynamic "principals" {
for_each = try(statement.value.principals, [])
for_each = statement.value.principals != null ? statement.value.principals : []
content {
type = principals.value.type
@@ -110,7 +124,7 @@ data "aws_iam_policy_document" "role" {
}
dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])
for_each = statement.value.not_principals != null ? statement.value.not_principals : []
content {
type = not_principals.value.type
@@ -119,7 +133,7 @@ data "aws_iam_policy_document" "role" {
}
dynamic "condition" {
for_each = try(statement.value.conditions, [])
for_each = statement.value.condition != null ? statement.value.condition : []
content {
test = condition.value.test
@@ -147,25 +161,28 @@ resource "aws_iam_role_policy" "this" {
resource "aws_eks_fargate_profile" "this" {
count = var.create ? 1 : 0
region = var.region
cluster_name = var.cluster_name
fargate_profile_name = var.name
pod_execution_role_arn = var.create_iam_role ? aws_iam_role.this[0].arn : var.iam_role_arn
subnet_ids = var.subnet_ids
dynamic "selector" {
for_each = var.selectors
for_each = var.selectors != null ? var.selectors : []
content {
namespace = selector.value.namespace
labels = lookup(selector.value, "labels", {})
labels = selector.value.labels
}
}
dynamic "timeouts" {
for_each = [var.timeouts]
for_each = var.timeouts != null ? [var.timeouts] : []
content {
create = lookup(var.timeouts, "create", null)
delete = lookup(var.timeouts, "delete", null)
create = var.timeouts.create
delete = var.timeouts.delete
}
}
+63 -8
View File
@@ -2,12 +2,32 @@ variable "create" {
description = "Determines whether to create Fargate profile or not"
type = bool
default = true
nullable = false
}
variable "tags" {
description = "A map of tags to add to all resources"
type = map(string)
default = {}
nullable = false
}
variable "region" {
description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration"
type = string
default = null
}
variable "partition" {
description = "The AWS partition - pass through value to reduce number of GET requests from data sources"
type = string
default = ""
}
variable "account_id" {
description = "The AWS account ID - pass through value to reduce number of GET requests from data sources"
type = string
default = ""
}
################################################################################
@@ -18,6 +38,7 @@ variable "create_iam_role" {
description = "Determines whether an IAM role is created or to use an existing IAM role"
type = bool
default = true
nullable = false
}
variable "cluster_ip_family" {
@@ -42,6 +63,7 @@ variable "iam_role_use_name_prefix" {
description = "Determines whether the IAM role name (`iam_role_name`) is used as a prefix"
type = bool
default = true
nullable = false
}
variable "iam_role_path" {
@@ -53,7 +75,8 @@ variable "iam_role_path" {
variable "iam_role_description" {
description = "Description of the role"
type = string
default = null
default = "Fargate profile IAM role"
nullable = false
}
variable "iam_role_permissions_boundary" {
@@ -66,18 +89,21 @@ variable "iam_role_attach_cni_policy" {
description = "Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster"
type = bool
default = true
nullable = false
}
variable "iam_role_additional_policies" {
description = "Additional policies to be added to the IAM role"
type = map(string)
default = {}
nullable = false
}
variable "iam_role_tags" {
description = "A map of additional tags to add to the IAM role created"
type = map(string)
default = {}
nullable = false
}
################################################################################
@@ -88,12 +114,33 @@ variable "create_iam_role_policy" {
description = "Determines whether an IAM role policy is created or not"
type = bool
default = true
nullable = false
}
variable "iam_role_policy_statements" {
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
type = any
default = []
type = list(object({
sid = optional(string)
actions = optional(list(string))
not_actions = optional(list(string))
effect = optional(string)
resources = optional(list(string))
not_resources = optional(list(string))
principals = optional(list(object({
type = string
identifiers = list(string)
})))
not_principals = optional(list(object({
type = string
identifiers = list(string)
})))
condition = optional(list(object({
test = string
values = list(string)
variable = string
})))
}))
default = null
}
################################################################################
@@ -103,29 +150,37 @@ variable "iam_role_policy_statements" {
variable "cluster_name" {
description = "Name of the EKS cluster"
type = string
default = null
default = ""
}
variable "name" {
description = "Name of the EKS Fargate Profile"
type = string
default = ""
nullable = false
}
variable "subnet_ids" {
description = "A list of subnet IDs for the EKS Fargate Profile"
type = list(string)
default = []
nullable = false
}
variable "selectors" {
description = "Configuration block(s) for selecting Kubernetes Pods to execute with this Fargate Profile"
type = any
default = []
type = list(object({
labels = optional(map(string))
namespace = string
}))
default = null
}
variable "timeouts" {
description = "Create and delete timeout configurations for the Fargate Profile"
type = map(string)
default = {}
type = object({
create = optional(string)
delete = optional(string)
})
default = null
}
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+7 -7
View File
@@ -74,14 +74,14 @@ module "eks_hybrid_node_role" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -115,7 +115,7 @@ No modules.
| <a name="input_enable_ira"></a> [enable\_ira](#input\_enable\_ira) | Enables IAM Roles Anywhere based IAM permissions on the node | `bool` | `false` | no |
| <a name="input_enable_pod_identity"></a> [enable\_pod\_identity](#input\_enable\_pod\_identity) | Enables EKS Pod Identity based IAM permissions on the node | `bool` | `true` | no |
| <a name="input_intermediate_policy_name"></a> [intermediate\_policy\_name](#input\_intermediate\_policy\_name) | Name of the IAM policy | `string` | `null` | no |
| <a name="input_intermediate_policy_statements"></a> [intermediate\_policy\_statements](#input\_intermediate\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
| <a name="input_intermediate_policy_statements"></a> [intermediate\_policy\_statements](#input\_intermediate\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | <pre>list(object({<br/> sid = optional(string)<br/> actions = optional(list(string))<br/> not_actions = optional(list(string))<br/> effect = optional(string)<br/> resources = optional(list(string))<br/> not_resources = optional(list(string))<br/> principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> not_principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> condition = optional(list(object({<br/> test = string<br/> values = list(string)<br/> variable = string<br/> })))<br/> }))</pre> | `null` | no |
| <a name="input_intermediate_policy_use_name_prefix"></a> [intermediate\_policy\_use\_name\_prefix](#input\_intermediate\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`intermediate_policy_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_intermediate_role_description"></a> [intermediate\_role\_description](#input\_intermediate\_role\_description) | IAM role description | `string` | `"EKS Hybrid Node IAM Roles Anywhere intermediate IAM role"` | no |
| <a name="input_intermediate_role_name"></a> [intermediate\_role\_name](#input\_intermediate\_role\_name) | Name of the IAM role | `string` | `null` | no |
@@ -129,7 +129,7 @@ No modules.
| <a name="input_ira_profile_session_policy"></a> [ira\_profile\_session\_policy](#input\_ira\_profile\_session\_policy) | A session policy that applies to the trust boundary of the vended session credentials | `string` | `null` | no |
| <a name="input_ira_trust_anchor_acm_pca_arn"></a> [ira\_trust\_anchor\_acm\_pca\_arn](#input\_ira\_trust\_anchor\_acm\_pca\_arn) | The ARN of the ACM PCA that issued the trust anchor certificate | `string` | `null` | no |
| <a name="input_ira_trust_anchor_name"></a> [ira\_trust\_anchor\_name](#input\_ira\_trust\_anchor\_name) | Name of the Roles Anywhere trust anchor | `string` | `null` | no |
| <a name="input_ira_trust_anchor_notification_settings"></a> [ira\_trust\_anchor\_notification\_settings](#input\_ira\_trust\_anchor\_notification\_settings) | Notification settings for the trust anchor | `any` | `[]` | no |
| <a name="input_ira_trust_anchor_notification_settings"></a> [ira\_trust\_anchor\_notification\_settings](#input\_ira\_trust\_anchor\_notification\_settings) | Notification settings for the trust anchor | <pre>list(object({<br/> channel = optional(string)<br/> enabled = optional(bool)<br/> event = optional(string)<br/> threshold = optional(number)<br/> }))</pre> | `null` | no |
| <a name="input_ira_trust_anchor_source_type"></a> [ira\_trust\_anchor\_source\_type](#input\_ira\_trust\_anchor\_source\_type) | The source type of the trust anchor | `string` | `null` | no |
| <a name="input_ira_trust_anchor_x509_certificate_data"></a> [ira\_trust\_anchor\_x509\_certificate\_data](#input\_ira\_trust\_anchor\_x509\_certificate\_data) | The X.509 certificate data of the trust anchor | `string` | `null` | no |
| <a name="input_max_session_duration"></a> [max\_session\_duration](#input\_max\_session\_duration) | Maximum API session duration in seconds between 3600 and 43200 | `number` | `null` | no |
@@ -140,9 +140,9 @@ No modules.
| <a name="input_policy_description"></a> [policy\_description](#input\_policy\_description) | IAM policy description | `string` | `"EKS Hybrid Node IAM role policy"` | no |
| <a name="input_policy_name"></a> [policy\_name](#input\_policy\_name) | Name of the IAM policy | `string` | `"EKSHybridNode"` | no |
| <a name="input_policy_path"></a> [policy\_path](#input\_policy\_path) | Path of the IAM policy | `string` | `"/"` | no |
| <a name="input_policy_statements"></a> [policy\_statements](#input\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
| <a name="input_policy_statements"></a> [policy\_statements](#input\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | <pre>list(object({<br/> sid = optional(string)<br/> actions = optional(list(string))<br/> not_actions = optional(list(string))<br/> effect = optional(string)<br/> resources = optional(list(string))<br/> not_resources = optional(list(string))<br/> principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> not_principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> condition = optional(list(object({<br/> test = string<br/> values = list(string)<br/> variable = string<br/> })))<br/> }))</pre> | `null` | no |
| <a name="input_policy_use_name_prefix"></a> [policy\_use\_name\_prefix](#input\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`policy_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of additional tags to add the the IAM role | `map(any)` | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of additional tags to add the the IAM role | `map(string)` | `{}` | no |
| <a name="input_trust_anchor_arns"></a> [trust\_anchor\_arns](#input\_trust\_anchor\_arns) | List of IAM Roles Anywhere trust anchor ARNs. Required if `enable_ira` is set to `true` | `list(string)` | `[]` | no |
| <a name="input_use_name_prefix"></a> [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether the name of the IAM role (`name`) is used as a prefix | `bool` | `true` | no |
+22 -22
View File
@@ -3,7 +3,7 @@ data "aws_partition" "current" {
}
locals {
partition = try(data.aws_partition.current[0].partition, "aws")
partition = try(data.aws_partition.current[0].partition, "")
}
################################################################################
@@ -117,18 +117,18 @@ data "aws_iam_policy_document" "this" {
}
dynamic "statement" {
for_each = var.policy_statements
for_each = var.policy_statements != null ? var.policy_statements : []
content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)
sid = statement.value.sid
actions = statement.value.actions
not_actions = statement.value.not_actions
effect = statement.value.effect
resources = statement.value.resources
not_resources = statement.value.not_resources
dynamic "principals" {
for_each = try(statement.value.principals, [])
for_each = statement.value.principals != null ? statement.value.principals : []
content {
type = principals.value.type
@@ -137,7 +137,7 @@ data "aws_iam_policy_document" "this" {
}
dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])
for_each = statement.value.not_principals != null ? statement.value.not_principals : []
content {
type = not_principals.value.type
@@ -146,7 +146,7 @@ data "aws_iam_policy_document" "this" {
}
dynamic "condition" {
for_each = try(statement.value.conditions, [])
for_each = statement.value.condition != null ? statement.value.condition : []
content {
test = condition.value.test
@@ -215,7 +215,7 @@ resource "aws_rolesanywhere_trust_anchor" "this" {
name = try(coalesce(var.ira_trust_anchor_name, var.name), null)
dynamic "notification_settings" {
for_each = var.ira_trust_anchor_notification_settings
for_each = var.ira_trust_anchor_notification_settings != null ? var.ira_trust_anchor_notification_settings : []
content {
channel = try(notification_settings.value.channel, null)
@@ -297,18 +297,18 @@ data "aws_iam_policy_document" "intermediate" {
}
dynamic "statement" {
for_each = var.intermediate_policy_statements
for_each = var.intermediate_policy_statements != null ? var.intermediate_policy_statements : []
content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)
sid = statement.value.sid
actions = statement.value.actions
not_actions = statement.value.not_actions
effect = statement.value.effect
resources = statement.value.resources
not_resources = statement.value.not_resources
dynamic "principals" {
for_each = try(statement.value.principals, [])
for_each = statement.value.principals != null ? statement.value.principals : []
content {
type = principals.value.type
@@ -317,7 +317,7 @@ data "aws_iam_policy_document" "intermediate" {
}
dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])
for_each = statement.value.not_principals != null ? statement.value.not_principals : []
content {
type = not_principals.value.type
@@ -326,7 +326,7 @@ data "aws_iam_policy_document" "intermediate" {
}
dynamic "condition" {
for_each = try(statement.value.conditions, [])
for_each = statement.value.condition != null ? statement.value.condition : []
content {
test = condition.value.test
+52 -7
View File
@@ -46,7 +46,7 @@ variable "permissions_boundary_arn" {
variable "tags" {
description = "A map of additional tags to add the the IAM role"
type = map(any)
type = map(string)
default = {}
}
@@ -92,8 +92,28 @@ variable "policy_description" {
variable "policy_statements" {
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
type = any
default = []
type = list(object({
sid = optional(string)
actions = optional(list(string))
not_actions = optional(list(string))
effect = optional(string)
resources = optional(list(string))
not_resources = optional(list(string))
principals = optional(list(object({
type = string
identifiers = list(string)
})))
not_principals = optional(list(object({
type = string
identifiers = list(string)
})))
condition = optional(list(object({
test = string
values = list(string)
variable = string
})))
}))
default = null
}
variable "policies" {
@@ -160,8 +180,13 @@ variable "ira_trust_anchor_name" {
variable "ira_trust_anchor_notification_settings" {
description = "Notification settings for the trust anchor"
type = any
default = []
type = list(object({
channel = optional(string)
enabled = optional(bool)
event = optional(string)
threshold = optional(number)
}))
default = null
}
variable "ira_trust_anchor_acm_pca_arn" {
@@ -228,8 +253,28 @@ variable "intermediate_policy_use_name_prefix" {
variable "intermediate_policy_statements" {
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
type = any
default = []
type = list(object({
sid = optional(string)
actions = optional(list(string))
not_actions = optional(list(string))
effect = optional(string)
resources = optional(list(string))
not_resources = optional(list(string))
principals = optional(list(object({
type = string
identifiers = list(string)
})))
not_principals = optional(list(object({
type = string
identifiers = list(string)
})))
condition = optional(list(object({
test = string
values = list(string)
variable = string
})))
}))
default = null
}
variable "intermediate_role_policies" {
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+9 -14
View File
@@ -85,14 +85,14 @@ module "karpenter" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -121,8 +121,6 @@ No modules.
| [aws_iam_policy_document.controller_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.node_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.queue](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.v033](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.v1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
@@ -139,27 +137,23 @@ No modules.
| <a name="input_create_iam_role"></a> [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created | `bool` | `true` | no |
| <a name="input_create_instance_profile"></a> [create\_instance\_profile](#input\_create\_instance\_profile) | Whether to create an IAM instance profile | `bool` | `false` | no |
| <a name="input_create_node_iam_role"></a> [create\_node\_iam\_role](#input\_create\_node\_iam\_role) | Determines whether an IAM role is created or to use an existing IAM role | `bool` | `true` | no |
| <a name="input_create_pod_identity_association"></a> [create\_pod\_identity\_association](#input\_create\_pod\_identity\_association) | Determines whether to create pod identity association | `bool` | `false` | no |
| <a name="input_enable_irsa"></a> [enable\_irsa](#input\_enable\_irsa) | Determines whether to enable support for IAM role for service accounts | `bool` | `false` | no |
| <a name="input_enable_pod_identity"></a> [enable\_pod\_identity](#input\_enable\_pod\_identity) | Determines whether to enable support for EKS pod identity | `bool` | `true` | no |
| <a name="input_create_pod_identity_association"></a> [create\_pod\_identity\_association](#input\_create\_pod\_identity\_association) | Determines whether to create pod identity association | `bool` | `true` | no |
| <a name="input_enable_spot_termination"></a> [enable\_spot\_termination](#input\_enable\_spot\_termination) | Determines whether to enable native spot termination handling | `bool` | `true` | no |
| <a name="input_enable_v1_permissions"></a> [enable\_v1\_permissions](#input\_enable\_v1\_permissions) | Determines whether to enable permissions suitable for v1+ (`true`) or for v0.33.x-v0.37.x (`false`) | `bool` | `false` | no |
| <a name="input_iam_policy_description"></a> [iam\_policy\_description](#input\_iam\_policy\_description) | IAM policy description | `string` | `"Karpenter controller IAM policy"` | no |
| <a name="input_iam_policy_name"></a> [iam\_policy\_name](#input\_iam\_policy\_name) | Name of the IAM policy | `string` | `"KarpenterController"` | no |
| <a name="input_iam_policy_path"></a> [iam\_policy\_path](#input\_iam\_policy\_path) | Path of the IAM policy | `string` | `"/"` | no |
| <a name="input_iam_policy_statements"></a> [iam\_policy\_statements](#input\_iam\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
| <a name="input_iam_policy_statements"></a> [iam\_policy\_statements](#input\_iam\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | <pre>list(object({<br/> sid = optional(string)<br/> actions = optional(list(string))<br/> not_actions = optional(list(string))<br/> effect = optional(string)<br/> resources = optional(list(string))<br/> not_resources = optional(list(string))<br/> principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> not_principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> condition = optional(list(object({<br/> test = string<br/> values = list(string)<br/> variable = string<br/> })))<br/> }))</pre> | `null` | no |
| <a name="input_iam_policy_use_name_prefix"></a> [iam\_policy\_use\_name\_prefix](#input\_iam\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`iam_policy_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | IAM role description | `string` | `"Karpenter controller IAM role"` | no |
| <a name="input_iam_role_max_session_duration"></a> [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | Maximum API session duration in seconds between 3600 and 43200 | `number` | `null` | no |
| <a name="input_iam_role_name"></a> [iam\_role\_name](#input\_iam\_role\_name) | Name of the IAM role | `string` | `"KarpenterController"` | no |
| <a name="input_iam_role_override_assume_policy_documents"></a> [iam\_role\_override\_assume\_policy\_documents](#input\_iam\_role\_override\_assume\_policy\_documents) | A list of IAM policy documents to override the default assume role policy document for the Karpenter controller IAM role | `list(string)` | `[]` | no |
| <a name="input_iam_role_path"></a> [iam\_role\_path](#input\_iam\_role\_path) | Path of the IAM role | `string` | `"/"` | no |
| <a name="input_iam_role_permissions_boundary_arn"></a> [iam\_role\_permissions\_boundary\_arn](#input\_iam\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for the IAM role | `string` | `null` | no |
| <a name="input_iam_role_policies"></a> [iam\_role\_policies](#input\_iam\_role\_policies) | Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format | `map(string)` | `{}` | no |
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add the the IAM role | `map(any)` | `{}` | no |
| <a name="input_iam_role_source_assume_policy_documents"></a> [iam\_role\_source\_assume\_policy\_documents](#input\_iam\_role\_source\_assume\_policy\_documents) | A list of IAM policy documents to use as a source for the assume role policy document for the Karpenter controller IAM role | `list(string)` | `[]` | no |
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add the the IAM role | `map(string)` | `{}` | no |
| <a name="input_iam_role_use_name_prefix"></a> [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the name of the IAM role (`iam_role_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_irsa_assume_role_condition_test"></a> [irsa\_assume\_role\_condition\_test](#input\_irsa\_assume\_role\_condition\_test) | Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role | `string` | `"StringEquals"` | no |
| <a name="input_irsa_namespace_service_accounts"></a> [irsa\_namespace\_service\_accounts](#input\_irsa\_namespace\_service\_accounts) | List of `namespace:serviceaccount`pairs to use in trust policy for IAM role for service accounts | `list(string)` | <pre>[<br/> "karpenter:karpenter"<br/>]</pre> | no |
| <a name="input_irsa_oidc_provider_arn"></a> [irsa\_oidc\_provider\_arn](#input\_irsa\_oidc\_provider\_arn) | OIDC provider arn used in trust policy for IAM role for service accounts | `string` | `""` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Namespace to associate with the Karpenter Pod Identity | `string` | `"kube-system"` | no |
| <a name="input_node_iam_role_additional_policies"></a> [node\_iam\_role\_additional\_policies](#input\_node\_iam\_role\_additional\_policies) | Additional policies to be added to the IAM role | `map(string)` | `{}` | no |
| <a name="input_node_iam_role_arn"></a> [node\_iam\_role\_arn](#input\_node\_iam\_role\_arn) | Existing IAM role ARN for the IAM instance profile. Required if `create_iam_role` is set to `false` | `string` | `null` | no |
@@ -175,6 +169,7 @@ No modules.
| <a name="input_queue_kms_master_key_id"></a> [queue\_kms\_master\_key\_id](#input\_queue\_kms\_master\_key\_id) | The ID of an AWS-managed customer master key (CMK) for Amazon SQS or a custom CMK | `string` | `null` | no |
| <a name="input_queue_managed_sse_enabled"></a> [queue\_managed\_sse\_enabled](#input\_queue\_managed\_sse\_enabled) | Boolean to enable server-side encryption (SSE) of message content with SQS-owned encryption keys | `bool` | `true` | no |
| <a name="input_queue_name"></a> [queue\_name](#input\_queue\_name) | Name of the SQS queue | `string` | `null` | no |
| <a name="input_region"></a> [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no |
| <a name="input_rule_name_prefix"></a> [rule\_name\_prefix](#input\_rule\_name\_prefix) | Prefix used for all event bridge rules | `string` | `"Karpenter"` | no |
| <a name="input_service_account"></a> [service\_account](#input\_service\_account) | Service account to associate with the Karpenter Pod Identity | `string` | `"karpenter"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
+35 -49
View File
@@ -1,12 +1,20 @@
data "aws_region" "current" {}
data "aws_partition" "current" {}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {
count = var.create ? 1 : 0
region = var.region
}
data "aws_partition" "current" {
count = var.create ? 1 : 0
}
data "aws_caller_identity" "current" {
count = var.create ? 1 : 0
}
locals {
account_id = data.aws_caller_identity.current.account_id
dns_suffix = data.aws_partition.current.dns_suffix
partition = data.aws_partition.current.partition
region = data.aws_region.current.name
account_id = try(data.aws_caller_identity.current[0].account_id, "")
dns_suffix = try(data.aws_partition.current[0].dns_suffix, "")
partition = try(data.aws_partition.current[0].partition, "")
region = try(data.aws_region.current[0].region, "")
}
################################################################################
@@ -15,17 +23,17 @@ locals {
locals {
create_iam_role = var.create && var.create_iam_role
irsa_oidc_provider_url = replace(var.irsa_oidc_provider_arn, "/^(.*provider/)/", "")
}
data "aws_iam_policy_document" "controller_assume_role" {
count = local.create_iam_role ? 1 : 0
# Pod Identity
dynamic "statement" {
for_each = var.enable_pod_identity ? [1] : []
override_policy_documents = var.iam_role_override_assume_policy_documents
source_policy_documents = var.iam_role_source_assume_policy_documents
content {
# Pod Identity
statement {
sid = "PodIdentity"
actions = [
"sts:AssumeRole",
"sts:TagSession",
@@ -36,34 +44,6 @@ data "aws_iam_policy_document" "controller_assume_role" {
identifiers = ["pods.eks.amazonaws.com"]
}
}
}
# IAM Roles for Service Accounts (IRSA)
dynamic "statement" {
for_each = var.enable_irsa ? [1] : []
content {
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [var.irsa_oidc_provider_arn]
}
condition {
test = var.irsa_assume_role_condition_test
variable = "${local.irsa_oidc_provider_url}:sub"
values = [for sa in var.irsa_namespace_service_accounts : "system:serviceaccount:${sa}"]
}
# https://aws.amazon.com/premiumsupport/knowledge-center/eks-troubleshoot-oidc-and-irsa/?nc1=h_ls
condition {
test = var.irsa_assume_role_condition_test
variable = "${local.irsa_oidc_provider_url}:aud"
values = ["sts.amazonaws.com"]
}
}
}
}
resource "aws_iam_role" "controller" {
@@ -82,12 +62,6 @@ resource "aws_iam_role" "controller" {
tags = merge(var.tags, var.iam_role_tags)
}
data "aws_iam_policy_document" "controller" {
count = local.create_iam_role ? 1 : 0
source_policy_documents = var.enable_v1_permissions ? [data.aws_iam_policy_document.v1[0].json] : [data.aws_iam_policy_document.v033[0].json]
}
resource "aws_iam_policy" "controller" {
count = local.create_iam_role ? 1 : 0
@@ -119,7 +93,9 @@ resource "aws_iam_role_policy_attachment" "controller_additional" {
################################################################################
resource "aws_eks_pod_identity_association" "karpenter" {
count = local.create_iam_role && var.enable_pod_identity && var.create_pod_identity_association ? 1 : 0
count = local.create_iam_role && var.create_pod_identity_association ? 1 : 0
region = var.region
cluster_name = var.cluster_name
namespace = var.namespace
@@ -142,6 +118,8 @@ locals {
resource "aws_sqs_queue" "this" {
count = local.enable_spot_termination ? 1 : 0
region = var.region
name = local.queue_name
message_retention_seconds = 300
sqs_managed_sse_enabled = var.queue_managed_sse_enabled ? var.queue_managed_sse_enabled : null
@@ -175,7 +153,7 @@ data "aws_iam_policy_document" "queue" {
]
resources = [aws_sqs_queue.this[0].arn]
condition {
test = "StringEquals"
test = "Bool"
variable = "aws:SecureTransport"
values = [
"false"
@@ -193,6 +171,8 @@ data "aws_iam_policy_document" "queue" {
resource "aws_sqs_queue_policy" "this" {
count = local.enable_spot_termination ? 1 : 0
region = var.region
queue_url = aws_sqs_queue.this[0].url
policy = data.aws_iam_policy_document.queue[0].json
}
@@ -241,6 +221,8 @@ locals {
resource "aws_cloudwatch_event_rule" "this" {
for_each = { for k, v in local.events : k => v if local.enable_spot_termination }
region = var.region
name_prefix = "${var.rule_name_prefix}${each.value.name}-"
description = each.value.description
event_pattern = jsonencode(each.value.event_pattern)
@@ -254,6 +236,8 @@ resource "aws_cloudwatch_event_rule" "this" {
resource "aws_cloudwatch_event_target" "this" {
for_each = { for k, v in local.events : k => v if local.enable_spot_termination }
region = var.region
rule = aws_cloudwatch_event_rule.this[each.key].name
target_id = "KarpenterInterruptionQueueTarget"
arn = aws_sqs_queue.this[0].arn
@@ -274,7 +258,7 @@ locals {
AmazonEKS_CNI_Policy = "${local.node_iam_role_policy_prefix}/AmazonEKS_CNI_Policy"
} : k => v if var.node_iam_role_attach_cni_policy && var.cluster_ip_family == "ipv4" }
ipv6_cni_policy = { for k, v in {
AmazonEKS_CNI_IPv6_Policy = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/AmazonEKS_CNI_IPv6_Policy"
AmazonEKS_CNI_IPv6_Policy = "arn:${local.partition}:iam::${local.account_id}:policy/AmazonEKS_CNI_IPv6_Policy"
} : k => v if var.node_iam_role_attach_cni_policy && var.cluster_ip_family == "ipv6" }
}
@@ -337,6 +321,8 @@ resource "aws_iam_role_policy_attachment" "node_additional" {
resource "aws_eks_access_entry" "node" {
count = var.create && var.create_access_entry ? 1 : 0
region = var.region
cluster_name = var.cluster_name
principal_arn = var.create_node_iam_role ? aws_iam_role.node[0].arn : var.node_iam_role_arn
type = var.access_entry_type
+11 -364
View File
@@ -1,357 +1,4 @@
################################################################################
# v0.33.x - v0.37.x Controller IAM Policy
################################################################################
data "aws_iam_policy_document" "v033" {
count = local.create_iam_role ? 1 : 0
statement {
sid = "AllowScopedEC2InstanceActions"
resources = [
"arn:${local.partition}:ec2:*::image/*",
"arn:${local.partition}:ec2:*::snapshot/*",
"arn:${local.partition}:ec2:*:*:spot-instances-request/*",
"arn:${local.partition}:ec2:*:*:security-group/*",
"arn:${local.partition}:ec2:*:*:subnet/*",
"arn:${local.partition}:ec2:*:*:launch-template/*",
]
actions = [
"ec2:RunInstances",
"ec2:CreateFleet"
]
}
statement {
sid = "AllowScopedEC2InstanceActionsWithTags"
resources = [
"arn:${local.partition}:ec2:*:*:fleet/*",
"arn:${local.partition}:ec2:*:*:instance/*",
"arn:${local.partition}:ec2:*:*:volume/*",
"arn:${local.partition}:ec2:*:*:network-interface/*",
"arn:${local.partition}:ec2:*:*:launch-template/*",
"arn:${local.partition}:ec2:*:*:spot-instances-request/*",
]
actions = [
"ec2:RunInstances",
"ec2:CreateFleet",
"ec2:CreateLaunchTemplate"
]
condition {
test = "StringEquals"
variable = "aws:RequestTag/kubernetes.io/cluster/${var.cluster_name}"
values = ["owned"]
}
condition {
test = "StringLike"
variable = "aws:RequestTag/karpenter.sh/nodepool"
values = ["*"]
}
}
statement {
sid = "AllowScopedResourceCreationTagging"
resources = [
"arn:${local.partition}:ec2:*:*:fleet/*",
"arn:${local.partition}:ec2:*:*:instance/*",
"arn:${local.partition}:ec2:*:*:volume/*",
"arn:${local.partition}:ec2:*:*:network-interface/*",
"arn:${local.partition}:ec2:*:*:launch-template/*",
"arn:${local.partition}:ec2:*:*:spot-instances-request/*",
]
actions = ["ec2:CreateTags"]
condition {
test = "StringEquals"
variable = "aws:RequestTag/kubernetes.io/cluster/${var.cluster_name}"
values = ["owned"]
}
condition {
test = "StringEquals"
variable = "ec2:CreateAction"
values = [
"RunInstances",
"CreateFleet",
"CreateLaunchTemplate",
]
}
condition {
test = "StringLike"
variable = "aws:RequestTag/karpenter.sh/nodepool"
values = ["*"]
}
}
statement {
sid = "AllowScopedResourceTagging"
resources = ["arn:${local.partition}:ec2:*:*:instance/*"]
actions = ["ec2:CreateTags"]
condition {
test = "StringEquals"
variable = "aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}"
values = ["owned"]
}
condition {
test = "StringLike"
variable = "aws:ResourceTag/karpenter.sh/nodepool"
values = ["*"]
}
condition {
test = "ForAllValues:StringEquals"
variable = "aws:TagKeys"
values = [
"karpenter.sh/nodeclaim",
"Name",
]
}
}
statement {
sid = "AllowScopedDeletion"
resources = [
"arn:${local.partition}:ec2:*:*:instance/*",
"arn:${local.partition}:ec2:*:*:launch-template/*"
]
actions = [
"ec2:TerminateInstances",
"ec2:DeleteLaunchTemplate"
]
condition {
test = "StringEquals"
variable = "aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}"
values = ["owned"]
}
condition {
test = "StringLike"
variable = "aws:ResourceTag/karpenter.sh/nodepool"
values = ["*"]
}
}
statement {
sid = "AllowRegionalReadActions"
resources = ["*"]
actions = [
"ec2:DescribeAvailabilityZones",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeInstanceTypeOfferings",
"ec2:DescribeInstanceTypes",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSpotPriceHistory",
"ec2:DescribeSubnets"
]
condition {
test = "StringEquals"
variable = "aws:RequestedRegion"
values = [local.region]
}
}
statement {
sid = "AllowSSMReadActions"
resources = coalescelist(var.ami_id_ssm_parameter_arns, ["arn:${local.partition}:ssm:${local.region}::parameter/aws/service/*"])
actions = ["ssm:GetParameter"]
}
statement {
sid = "AllowPricingReadActions"
resources = ["*"]
actions = ["pricing:GetProducts"]
}
dynamic "statement" {
for_each = local.enable_spot_termination ? [1] : []
content {
sid = "AllowInterruptionQueueActions"
resources = [try(aws_sqs_queue.this[0].arn, null)]
actions = [
"sqs:DeleteMessage",
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:ReceiveMessage"
]
}
}
statement {
sid = "AllowPassingInstanceRole"
resources = var.create_node_iam_role ? [aws_iam_role.node[0].arn] : [var.node_iam_role_arn]
actions = ["iam:PassRole"]
condition {
test = "StringEquals"
variable = "iam:PassedToService"
values = ["ec2.${local.dns_suffix}"]
}
}
statement {
sid = "AllowScopedInstanceProfileCreationActions"
resources = ["*"]
actions = ["iam:CreateInstanceProfile"]
condition {
test = "StringEquals"
variable = "aws:RequestTag/kubernetes.io/cluster/${var.cluster_name}"
values = ["owned"]
}
condition {
test = "StringEquals"
variable = "aws:RequestTag/topology.kubernetes.io/region"
values = [local.region]
}
condition {
test = "StringLike"
variable = "aws:RequestTag/karpenter.k8s.aws/ec2nodeclass"
values = ["*"]
}
}
statement {
sid = "AllowScopedInstanceProfileTagActions"
resources = ["*"]
actions = ["iam:TagInstanceProfile"]
condition {
test = "StringEquals"
variable = "aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}"
values = ["owned"]
}
condition {
test = "StringEquals"
variable = "aws:ResourceTag/topology.kubernetes.io/region"
values = [local.region]
}
condition {
test = "StringEquals"
variable = "aws:RequestTag/kubernetes.io/cluster/${var.cluster_name}"
values = ["owned"]
}
condition {
test = "StringEquals"
variable = "aws:ResourceTag/topology.kubernetes.io/region"
values = [local.region]
}
condition {
test = "StringLike"
variable = "aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass"
values = ["*"]
}
condition {
test = "StringLike"
variable = "aws:RequestTag/karpenter.k8s.aws/ec2nodeclass"
values = ["*"]
}
}
statement {
sid = "AllowScopedInstanceProfileActions"
resources = ["*"]
actions = [
"iam:AddRoleToInstanceProfile",
"iam:RemoveRoleFromInstanceProfile",
"iam:DeleteInstanceProfile"
]
condition {
test = "StringEquals"
variable = "aws:ResourceTag/kubernetes.io/cluster/${var.cluster_name}"
values = ["owned"]
}
condition {
test = "StringEquals"
variable = "aws:ResourceTag/topology.kubernetes.io/region"
values = [local.region]
}
condition {
test = "StringLike"
variable = "aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass"
values = ["*"]
}
}
statement {
sid = "AllowInstanceProfileReadActions"
resources = ["*"]
actions = ["iam:GetInstanceProfile"]
}
statement {
sid = "AllowAPIServerEndpointDiscovery"
resources = ["arn:${local.partition}:eks:${local.region}:${local.account_id}:cluster/${var.cluster_name}"]
actions = ["eks:DescribeCluster"]
}
dynamic "statement" {
for_each = var.iam_policy_statements
content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)
dynamic "principals" {
for_each = try(statement.value.principals, [])
content {
type = principals.value.type
identifiers = principals.value.identifiers
}
}
dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])
content {
type = not_principals.value.type
identifiers = not_principals.value.identifiers
}
}
dynamic "condition" {
for_each = try(statement.value.conditions, [])
content {
test = condition.value.test
values = condition.value.values
variable = condition.value.variable
}
}
}
}
}
################################################################################
# v1.0.x Controller IAM Policy
################################################################################
data "aws_iam_policy_document" "v1" {
data "aws_iam_policy_document" "controller" {
count = local.create_iam_role ? 1 : 0
statement {
@@ -708,18 +355,18 @@ data "aws_iam_policy_document" "v1" {
}
dynamic "statement" {
for_each = var.iam_policy_statements
for_each = var.iam_policy_statements != null ? var.iam_policy_statements : []
content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)
sid = statement.value.sid
actions = statement.value.actions
not_actions = statement.value.not_actions
effect = statement.value.effect
resources = statement.value.resources
not_resources = statement.value.not_resources
dynamic "principals" {
for_each = try(statement.value.principals, [])
for_each = statement.value.principals != null ? statement.value.principals : []
content {
type = principals.value.type
@@ -728,7 +375,7 @@ data "aws_iam_policy_document" "v1" {
}
dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])
for_each = statement.value.not_principals != null ? statement.value.not_principals : []
content {
type = not_principals.value.type
@@ -737,7 +384,7 @@ data "aws_iam_policy_document" "v1" {
}
dynamic "condition" {
for_each = try(statement.value.conditions, [])
for_each = statement.value.condition != null ? statement.value.condition : []
content {
test = condition.value.test
+43 -46
View File
@@ -16,6 +16,12 @@ variable "cluster_name" {
default = ""
}
variable "region" {
description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration"
type = string
default = null
}
################################################################################
# Karpenter controller IAM Role
################################################################################
@@ -64,7 +70,7 @@ variable "iam_role_permissions_boundary_arn" {
variable "iam_role_tags" {
description = "A map of additional tags to add the the IAM role"
type = map(any)
type = map(string)
default = {}
}
@@ -92,10 +98,42 @@ variable "iam_policy_description" {
default = "Karpenter controller IAM policy"
}
variable "iam_role_override_assume_policy_documents" {
description = "A list of IAM policy documents to override the default assume role policy document for the Karpenter controller IAM role"
type = list(string)
default = []
}
variable "iam_role_source_assume_policy_documents" {
description = "A list of IAM policy documents to use as a source for the assume role policy document for the Karpenter controller IAM role"
type = list(string)
default = []
}
variable "iam_policy_statements" {
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
type = any
default = []
type = list(object({
sid = optional(string)
actions = optional(list(string))
not_actions = optional(list(string))
effect = optional(string)
resources = optional(list(string))
not_resources = optional(list(string))
principals = optional(list(object({
type = string
identifiers = list(string)
})))
not_principals = optional(list(object({
type = string
identifiers = list(string)
})))
condition = optional(list(object({
test = string
values = list(string)
variable = string
})))
}))
default = null
}
variable "iam_role_policies" {
@@ -110,55 +148,14 @@ variable "ami_id_ssm_parameter_arns" {
default = []
}
variable "enable_pod_identity" {
description = "Determines whether to enable support for EKS pod identity"
type = bool
default = true
}
# TODO - make v1 permssions the default policy at next breaking change
variable "enable_v1_permissions" {
description = "Determines whether to enable permissions suitable for v1+ (`true`) or for v0.33.x-v0.37.x (`false`)"
type = bool
default = false
}
################################################################################
# IAM Role for Service Account (IRSA)
################################################################################
variable "enable_irsa" {
description = "Determines whether to enable support for IAM role for service accounts"
type = bool
default = false
}
variable "irsa_oidc_provider_arn" {
description = "OIDC provider arn used in trust policy for IAM role for service accounts"
type = string
default = ""
}
variable "irsa_namespace_service_accounts" {
description = "List of `namespace:serviceaccount`pairs to use in trust policy for IAM role for service accounts"
type = list(string)
default = ["karpenter:karpenter"]
}
variable "irsa_assume_role_condition_test" {
description = "Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role"
type = string
default = "StringEquals"
}
################################################################################
# Pod Identity Association
################################################################################
# TODO - Change default to `true` at next breaking change
variable "create_pod_identity_association" {
description = "Determines whether to create pod identity association"
type = bool
default = false
default = true
}
variable "namespace" {
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+60 -64
View File
@@ -10,7 +10,7 @@ module "self_managed_node_group" {
name = "separate-self-mng"
cluster_name = "my-cluster"
cluster_version = "1.31"
kubernetes_version = "1.31"
cluster_endpoint = "https://012345678903AB2BAE5D1E0BFE0E2B50.gr7.us-east-1.eks.amazonaws.com"
cluster_auth_base64 = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKbXFqQ1VqNGdGR2w3ZW5PeWthWnZ2RjROOTVOUEZCM2o0cGhVZUsrWGFtN2ZSQnZya0d6OGxKZmZEZWF2b2plTwpQK2xOZFlqdHZncmxCUEpYdHZIZmFzTzYxVzdIZmdWQ2EvamdRM2w3RmkvL1dpQmxFOG9oWUZkdWpjc0s1SXM2CnNkbk5KTTNYUWN2TysrSitkV09NT2ZlNzlsSWdncmdQLzgvRU9CYkw3eUY1aU1hS3lsb1RHL1V3TlhPUWt3ZUcKblBNcjdiUmdkQ1NCZTlXYXowOGdGRmlxV2FOditsTDhsODBTdFZLcWVNVlUxbjQyejVwOVpQRTd4T2l6L0xTNQpYV2lXWkVkT3pMN0xBWGVCS2gzdkhnczFxMkI2d1BKZnZnS1NzWllQRGFpZTloT1NNOUJkNFNPY3JrZTRYSVBOCkVvcXVhMlYrUDRlTWJEQzhMUkVWRDdCdVZDdWdMTldWOTBoL3VJUy9WU2VOcEdUOGVScE5DakszSjc2aFlsWm8KWjNGRG5QWUY0MWpWTHhiOXF0U1ROdEp6amYwWXBEYnFWci9xZzNmQWlxbVorMzd3YWM1eHlqMDZ4cmlaRUgzZgpUM002d2lCUEVHYVlGeWN5TmNYTk5aYW9DWDJVL0N1d2JsUHAKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ=="
@@ -42,14 +42,14 @@ module "self_managed_node_group" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -62,7 +62,6 @@ module "self_managed_node_group" {
| Name | Type |
|------|------|
| [aws_autoscaling_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource |
| [aws_autoscaling_schedule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource |
| [aws_eks_access_entry.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource |
| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
@@ -71,39 +70,41 @@ module "self_managed_node_group" {
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource |
| [aws_placement_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/placement_group) | resource |
| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
| [aws_vpc_security_group_egress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource |
| [aws_vpc_security_group_ingress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_ec2_instance_type.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type) | data source |
| [aws_ec2_instance_type_offerings.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type_offerings) | data source |
| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
| [aws_ssm_parameter.ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source |
| [aws_subnets.placement_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source |
| [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_cluster_dns_ips"></a> [additional\_cluster\_dns\_ips](#input\_additional\_cluster\_dns\_ips) | Additional DNS IP addresses to use for the cluster. Only used when `ami_type` = `BOTTLEROCKET_*` | `list(string)` | `[]` | no |
| <a name="input_account_id"></a> [account\_id](#input\_account\_id) | The AWS account ID - pass through value to reduce number of GET requests from data sources | `string` | `""` | no |
| <a name="input_additional_cluster_dns_ips"></a> [additional\_cluster\_dns\_ips](#input\_additional\_cluster\_dns\_ips) | Additional DNS IP addresses to use for the cluster. Only used when `ami_type` = `BOTTLEROCKET_*` | `list(string)` | `null` | no |
| <a name="input_ami_id"></a> [ami\_id](#input\_ami\_id) | The AMI from which to launch the instance | `string` | `""` | no |
| <a name="input_ami_type"></a> [ami\_type](#input\_ami\_type) | Type of Amazon Machine Image (AMI) associated with the node group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values | `string` | `"AL2_x86_64"` | no |
| <a name="input_ami_type"></a> [ami\_type](#input\_ami\_type) | Type of Amazon Machine Image (AMI) associated with the node group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values | `string` | `"AL2023_x86_64_STANDARD"` | no |
| <a name="input_autoscaling_group_tags"></a> [autoscaling\_group\_tags](#input\_autoscaling\_group\_tags) | A map of additional tags to add to the autoscaling group created. Tags are applied to the autoscaling group only and are NOT propagated to instances | `map(string)` | `{}` | no |
| <a name="input_availability_zones"></a> [availability\_zones](#input\_availability\_zones) | A list of one or more availability zones for the group. Used for EC2-Classic and default subnets when not specified with `subnet_ids` argument. Conflicts with `subnet_ids` | `list(string)` | `null` | no |
| <a name="input_block_device_mappings"></a> [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI | `any` | `{}` | no |
| <a name="input_bootstrap_extra_args"></a> [bootstrap\_extra\_args](#input\_bootstrap\_extra\_args) | Additional arguments passed to the bootstrap script. When `ami_type` = `BOTTLEROCKET_*`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data | `string` | `""` | no |
| <a name="input_block_device_mappings"></a> [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI | <pre>map(object({<br/> device_name = optional(string)<br/> ebs = optional(object({<br/> delete_on_termination = optional(bool)<br/> encrypted = optional(bool)<br/> iops = optional(number)<br/> kms_key_id = optional(string)<br/> snapshot_id = optional(string)<br/> throughput = optional(number)<br/> volume_initialization_rate = optional(number)<br/> volume_size = optional(number)<br/> volume_type = optional(string)<br/> }))<br/> no_device = optional(string)<br/> virtual_name = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_bootstrap_extra_args"></a> [bootstrap\_extra\_args](#input\_bootstrap\_extra\_args) | Additional arguments passed to the bootstrap script. When `ami_type` = `BOTTLEROCKET_*`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data | `string` | `null` | no |
| <a name="input_capacity_rebalance"></a> [capacity\_rebalance](#input\_capacity\_rebalance) | Indicates whether capacity rebalance is enabled | `bool` | `null` | no |
| <a name="input_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Targeting for EC2 capacity reservations | `any` | `{}` | no |
| <a name="input_cloudinit_post_nodeadm"></a> [cloudinit\_post\_nodeadm](#input\_cloudinit\_post\_nodeadm) | Array of cloud-init document parts that are created after the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_cloudinit_pre_nodeadm"></a> [cloudinit\_pre\_nodeadm](#input\_cloudinit\_pre\_nodeadm) | Array of cloud-init document parts that are created before the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_cluster_auth_base64"></a> [cluster\_auth\_base64](#input\_cluster\_auth\_base64) | Base64 encoded CA of associated EKS cluster | `string` | `""` | no |
| <a name="input_cluster_endpoint"></a> [cluster\_endpoint](#input\_cluster\_endpoint) | Endpoint of associated EKS cluster | `string` | `""` | no |
| <a name="input_cluster_ip_family"></a> [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6` | `string` | `"ipv4"` | no |
| <a name="input_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Targeting for EC2 capacity reservations | <pre>object({<br/> capacity_reservation_preference = optional(string)<br/> capacity_reservation_target = optional(object({<br/> capacity_reservation_id = optional(string)<br/> capacity_reservation_resource_group_arn = optional(string)<br/> }))<br/> })</pre> | `null` | no |
| <a name="input_cloudinit_post_nodeadm"></a> [cloudinit\_post\_nodeadm](#input\_cloudinit\_post\_nodeadm) | Array of cloud-init document parts that are created after the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_cloudinit_pre_nodeadm"></a> [cloudinit\_pre\_nodeadm](#input\_cloudinit\_pre\_nodeadm) | Array of cloud-init document parts that are created before the nodeadm document part | <pre>list(object({<br/> content = string<br/> content_type = optional(string)<br/> filename = optional(string)<br/> merge_type = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_cluster_auth_base64"></a> [cluster\_auth\_base64](#input\_cluster\_auth\_base64) | Base64 encoded CA of associated EKS cluster | `string` | `null` | no |
| <a name="input_cluster_endpoint"></a> [cluster\_endpoint](#input\_cluster\_endpoint) | Endpoint of associated EKS cluster | `string` | `null` | no |
| <a name="input_cluster_ip_family"></a> [cluster\_ip\_family](#input\_cluster\_ip\_family) | The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6` | `string` | `null` | no |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of associated EKS cluster | `string` | `""` | no |
| <a name="input_cluster_primary_security_group_id"></a> [cluster\_primary\_security\_group\_id](#input\_cluster\_primary\_security\_group\_id) | The ID of the EKS cluster primary security group to associate with the instance(s). This is the security group that is automatically created by the EKS service | `string` | `null` | no |
| <a name="input_cluster_service_cidr"></a> [cluster\_service\_cidr](#input\_cluster\_service\_cidr) | The CIDR block (IPv4 or IPv6) used by the cluster to assign Kubernetes service IP addresses. This is derived from the cluster itself | `string` | `""` | no |
| <a name="input_cluster_version"></a> [cluster\_version](#input\_cluster\_version) | Kubernetes cluster version - used to lookup default AMI ID if one is not provided | `string` | `null` | no |
| <a name="input_cluster_service_cidr"></a> [cluster\_service\_cidr](#input\_cluster\_service\_cidr) | The CIDR block (IPv4 or IPv6) used by the cluster to assign Kubernetes service IP addresses. This is derived from the cluster itself | `string` | `null` | no |
| <a name="input_context"></a> [context](#input\_context) | Reserved | `string` | `null` | no |
| <a name="input_cpu_options"></a> [cpu\_options](#input\_cpu\_options) | The CPU options for the instance | `map(string)` | `{}` | no |
| <a name="input_cpu_options"></a> [cpu\_options](#input\_cpu\_options) | The CPU options for the instance | <pre>object({<br/> amd_sev_snp = optional(string)<br/> core_count = optional(number)<br/> threads_per_core = optional(number)<br/> })</pre> | `null` | no |
| <a name="input_create"></a> [create](#input\_create) | Determines whether to create self managed node group or not | `bool` | `true` | no |
| <a name="input_create_access_entry"></a> [create\_access\_entry](#input\_create\_access\_entry) | Determines whether an access entry is created for the IAM role used by the node group | `bool` | `true` | no |
| <a name="input_create_autoscaling_group"></a> [create\_autoscaling\_group](#input\_create\_autoscaling\_group) | Determines whether to create autoscaling group or not | `bool` | `true` | no |
@@ -111,49 +112,44 @@ module "self_managed_node_group" {
| <a name="input_create_iam_role_policy"></a> [create\_iam\_role\_policy](#input\_create\_iam\_role\_policy) | Determines whether an IAM role policy is created or not | `bool` | `true` | no |
| <a name="input_create_launch_template"></a> [create\_launch\_template](#input\_create\_launch\_template) | Determines whether to create launch template or not | `bool` | `true` | no |
| <a name="input_create_placement_group"></a> [create\_placement\_group](#input\_create\_placement\_group) | Determines whether a placement group is created & used by the node group | `bool` | `false` | no |
| <a name="input_create_schedule"></a> [create\_schedule](#input\_create\_schedule) | Determines whether to create autoscaling group schedule or not | `bool` | `true` | no |
| <a name="input_credit_specification"></a> [credit\_specification](#input\_credit\_specification) | Customize the credit specification of the instance | `map(string)` | `{}` | no |
| <a name="input_default_cooldown"></a> [default\_cooldown](#input\_default\_cooldown) | The amount of time, in seconds, after a scaling activity completes before another scaling activity can start | `number` | `null` | no |
| <a name="input_create_security_group"></a> [create\_security\_group](#input\_create\_security\_group) | Determines if a security group is created | `bool` | `true` | no |
| <a name="input_credit_specification"></a> [credit\_specification](#input\_credit\_specification) | Customize the credit specification of the instance | <pre>object({<br/> cpu_credits = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_default_instance_warmup"></a> [default\_instance\_warmup](#input\_default\_instance\_warmup) | Amount of time, in seconds, until a newly launched instance can contribute to the Amazon CloudWatch metrics. This delay lets an instance finish initializing before Amazon EC2 Auto Scaling aggregates instance metrics, resulting in more reliable usage data | `number` | `null` | no |
| <a name="input_delete_timeout"></a> [delete\_timeout](#input\_delete\_timeout) | Delete timeout to wait for destroying autoscaling group | `string` | `null` | no |
| <a name="input_desired_size"></a> [desired\_size](#input\_desired\_size) | The number of Amazon EC2 instances that should be running in the autoscaling group | `number` | `1` | no |
| <a name="input_desired_size_type"></a> [desired\_size\_type](#input\_desired\_size\_type) | The unit of measurement for the value specified for `desired_size`. Supported for attribute-based instance type selection only. Valid values: `units`, `vcpu`, `memory-mib` | `string` | `null` | no |
| <a name="input_disable_api_termination"></a> [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 instance termination protection | `bool` | `null` | no |
| <a name="input_ebs_optimized"></a> [ebs\_optimized](#input\_ebs\_optimized) | If true, the launched EC2 instance will be EBS-optimized | `bool` | `null` | no |
| <a name="input_efa_indices"></a> [efa\_indices](#input\_efa\_indices) | The indices of the network interfaces that should be EFA-enabled. Only valid when `enable_efa_support` = `true` | `list(number)` | <pre>[<br/> 0<br/>]</pre> | no |
| <a name="input_elastic_gpu_specifications"></a> [elastic\_gpu\_specifications](#input\_elastic\_gpu\_specifications) | The elastic GPU to attach to the instance | `any` | `{}` | no |
| <a name="input_elastic_inference_accelerator"></a> [elastic\_inference\_accelerator](#input\_elastic\_inference\_accelerator) | Configuration block containing an Elastic Inference Accelerator to attach to the instance | `map(string)` | `{}` | no |
| <a name="input_enable_efa_only"></a> [enable\_efa\_only](#input\_enable\_efa\_only) | Determines whether to enable EFA (`false`, default) or EFA and EFA-only (`true`) network interfaces. Note: requires vpc-cni version `v1.18.4` or later | `bool` | `false` | no |
| <a name="input_enable_efa_only"></a> [enable\_efa\_only](#input\_enable\_efa\_only) | Determines whether to enable EFA (`false`, default) or EFA and EFA-only (`true`) network interfaces. Note: requires vpc-cni version `v1.18.4` or later | `bool` | `true` | no |
| <a name="input_enable_efa_support"></a> [enable\_efa\_support](#input\_enable\_efa\_support) | Determines whether to enable Elastic Fabric Adapter (EFA) support | `bool` | `false` | no |
| <a name="input_enable_monitoring"></a> [enable\_monitoring](#input\_enable\_monitoring) | Enables/disables detailed monitoring | `bool` | `true` | no |
| <a name="input_enable_monitoring"></a> [enable\_monitoring](#input\_enable\_monitoring) | Enables/disables detailed monitoring | `bool` | `false` | no |
| <a name="input_enabled_metrics"></a> [enabled\_metrics](#input\_enabled\_metrics) | A list of metrics to collect. The allowed values are `GroupDesiredCapacity`, `GroupInServiceCapacity`, `GroupPendingCapacity`, `GroupMinSize`, `GroupMaxSize`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupStandbyCapacity`, `GroupTerminatingCapacity`, `GroupTerminatingInstances`, `GroupTotalCapacity`, `GroupTotalInstances` | `list(string)` | `[]` | no |
| <a name="input_enclave_options"></a> [enclave\_options](#input\_enclave\_options) | Enable Nitro Enclaves on launched instances | `map(string)` | `{}` | no |
| <a name="input_enclave_options"></a> [enclave\_options](#input\_enclave\_options) | Enable Nitro Enclaves on launched instances | <pre>object({<br/> enabled = optional(bool)<br/> })</pre> | `null` | no |
| <a name="input_force_delete"></a> [force\_delete](#input\_force\_delete) | Allows deleting the Auto Scaling Group without waiting for all instances in the pool to terminate. You can force an Auto Scaling Group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling | `bool` | `null` | no |
| <a name="input_force_delete_warm_pool"></a> [force\_delete\_warm\_pool](#input\_force\_delete\_warm\_pool) | Allows deleting the Auto Scaling Group without waiting for all instances in the warm pool to terminate | `bool` | `null` | no |
| <a name="input_health_check_grace_period"></a> [health\_check\_grace\_period](#input\_health\_check\_grace\_period) | Time (in seconds) after instance comes into service before checking health | `number` | `null` | no |
| <a name="input_health_check_type"></a> [health\_check\_type](#input\_health\_check\_type) | `EC2` or `ELB`. Controls how health checking is done | `string` | `null` | no |
| <a name="input_hibernation_options"></a> [hibernation\_options](#input\_hibernation\_options) | The hibernation options for the instance | `map(string)` | `{}` | no |
| <a name="input_iam_instance_profile_arn"></a> [iam\_instance\_profile\_arn](#input\_iam\_instance\_profile\_arn) | Amazon Resource Name (ARN) of an existing IAM instance profile that provides permissions for the node group. Required if `create_iam_instance_profile` = `false` | `string` | `null` | no |
| <a name="input_iam_role_additional_policies"></a> [iam\_role\_additional\_policies](#input\_iam\_role\_additional\_policies) | Additional policies to be added to the IAM role | `map(string)` | `{}` | no |
| <a name="input_iam_role_arn"></a> [iam\_role\_arn](#input\_iam\_role\_arn) | ARN of the IAM role used by the instance profile. Required when `create_access_entry = true` and `create_iam_instance_profile = false` | `string` | `null` | no |
| <a name="input_iam_role_attach_cni_policy"></a> [iam\_role\_attach\_cni\_policy](#input\_iam\_role\_attach\_cni\_policy) | Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster | `bool` | `true` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `"Self managed node group IAM role"` | no |
| <a name="input_iam_role_name"></a> [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no |
| <a name="input_iam_role_path"></a> [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no |
| <a name="input_iam_role_permissions_boundary"></a> [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no |
| <a name="input_iam_role_policy_statements"></a> [iam\_role\_policy\_statements](#input\_iam\_role\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
| <a name="input_iam_role_policy_statements"></a> [iam\_role\_policy\_statements](#input\_iam\_role\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | <pre>list(object({<br/> sid = optional(string)<br/> actions = optional(list(string))<br/> not_actions = optional(list(string))<br/> effect = optional(string)<br/> resources = optional(list(string))<br/> not_resources = optional(list(string))<br/> principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> not_principals = optional(list(object({<br/> type = string<br/> identifiers = list(string)<br/> })))<br/> condition = optional(list(object({<br/> test = string<br/> values = list(string)<br/> variable = string<br/> })))<br/> }))</pre> | `null` | no |
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role created | `map(string)` | `{}` | no |
| <a name="input_iam_role_use_name_prefix"></a> [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether cluster IAM role name (`iam_role_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_ignore_failed_scaling_activities"></a> [ignore\_failed\_scaling\_activities](#input\_ignore\_failed\_scaling\_activities) | Whether to ignore failed Auto Scaling scaling activities while waiting for capacity. | `bool` | `null` | no |
| <a name="input_initial_lifecycle_hooks"></a> [initial\_lifecycle\_hooks](#input\_initial\_lifecycle\_hooks) | One or more Lifecycle Hooks to attach to the Auto Scaling Group before instances are launched. The syntax is exactly the same as the separate `aws_autoscaling_lifecycle_hook` resource, without the `autoscaling_group_name` attribute. Please note that this will only work when creating a new Auto Scaling Group. For all other use-cases, please use `aws_autoscaling_lifecycle_hook` resource | `list(map(string))` | `[]` | no |
| <a name="input_ignore_failed_scaling_activities"></a> [ignore\_failed\_scaling\_activities](#input\_ignore\_failed\_scaling\_activities) | Whether to ignore failed Auto Scaling scaling activities while waiting for capacity | `bool` | `null` | no |
| <a name="input_initial_lifecycle_hooks"></a> [initial\_lifecycle\_hooks](#input\_initial\_lifecycle\_hooks) | One or more Lifecycle Hooks to attach to the Auto Scaling Group before instances are launched. The syntax is exactly the same as the separate `aws_autoscaling_lifecycle_hook` resource, without the `autoscaling_group_name` attribute. Please note that this will only work when creating a new Auto Scaling Group. For all other use-cases, please use `aws_autoscaling_lifecycle_hook` resource | <pre>list(object({<br/> default_result = optional(string)<br/> heartbeat_timeout = optional(number)<br/> lifecycle_transition = string<br/> name = string<br/> notification_metadata = optional(string)<br/> notification_target_arn = optional(string)<br/> role_arn = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_instance_initiated_shutdown_behavior"></a> [instance\_initiated\_shutdown\_behavior](#input\_instance\_initiated\_shutdown\_behavior) | Shutdown behavior for the instance. Can be `stop` or `terminate`. (Default: `stop`) | `string` | `null` | no |
| <a name="input_instance_maintenance_policy"></a> [instance\_maintenance\_policy](#input\_instance\_maintenance\_policy) | If this block is configured, add a instance maintenance policy to the specified Auto Scaling group | `any` | `{}` | no |
| <a name="input_instance_market_options"></a> [instance\_market\_options](#input\_instance\_market\_options) | The market (purchasing) option for the instance | `any` | `{}` | no |
| <a name="input_instance_refresh"></a> [instance\_refresh](#input\_instance\_refresh) | If this block is configured, start an Instance Refresh when this Auto Scaling Group is updated | `any` | <pre>{<br/> "preferences": {<br/> "min_healthy_percentage": 66<br/> },<br/> "strategy": "Rolling"<br/>}</pre> | no |
| <a name="input_instance_requirements"></a> [instance\_requirements](#input\_instance\_requirements) | The attribute requirements for the type of instance. If present then `instance_type` cannot be present | `any` | `{}` | no |
| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | The type of the instance to launch | `string` | `""` | no |
| <a name="input_instance_maintenance_policy"></a> [instance\_maintenance\_policy](#input\_instance\_maintenance\_policy) | If this block is configured, add a instance maintenance policy to the specified Auto Scaling group | <pre>object({<br/> max_healthy_percentage = number<br/> min_healthy_percentage = number<br/> })</pre> | `null` | no |
| <a name="input_instance_market_options"></a> [instance\_market\_options](#input\_instance\_market\_options) | The market (purchasing) option for the instance | <pre>object({<br/> market_type = optional(string)<br/> spot_options = optional(object({<br/> block_duration_minutes = optional(number)<br/> instance_interruption_behavior = optional(string)<br/> max_price = optional(string)<br/> spot_instance_type = optional(string)<br/> valid_until = optional(string)<br/> }))<br/> })</pre> | `null` | no |
| <a name="input_instance_refresh"></a> [instance\_refresh](#input\_instance\_refresh) | If this block is configured, start an Instance Refresh when this Auto Scaling Group is updated | <pre>object({<br/> preferences = optional(object({<br/> alarm_specification = optional(object({<br/> alarms = optional(list(string))<br/> }))<br/> auto_rollback = optional(bool)<br/> checkpoint_delay = optional(number)<br/> checkpoint_percentages = optional(list(number))<br/> instance_warmup = optional(number)<br/> max_healthy_percentage = optional(number)<br/> min_healthy_percentage = optional(number, 33)<br/> scale_in_protected_instances = optional(string)<br/> skip_matching = optional(bool)<br/> standby_instances = optional(string)<br/> }))<br/> strategy = optional(string, "Rolling")<br/> triggers = optional(list(string))<br/> })</pre> | <pre>{<br/> "preferences": {<br/> "min_healthy_percentage": 66<br/> },<br/> "strategy": "Rolling"<br/>}</pre> | no |
| <a name="input_instance_requirements"></a> [instance\_requirements](#input\_instance\_requirements) | The attribute requirements for the type of instance. If present then `instance_type` cannot be present | <pre>object({<br/> accelerator_count = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> accelerator_manufacturers = optional(list(string))<br/> accelerator_names = optional(list(string))<br/> accelerator_total_memory_mib = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> accelerator_types = optional(list(string))<br/> allowed_instance_types = optional(list(string))<br/> bare_metal = optional(string)<br/> baseline_ebs_bandwidth_mbps = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> burstable_performance = optional(string)<br/> cpu_manufacturers = optional(list(string))<br/> excluded_instance_types = optional(list(string))<br/> instance_generations = optional(list(string))<br/> local_storage = optional(string)<br/> local_storage_types = optional(list(string))<br/> max_spot_price_as_percentage_of_optimal_on_demand_price = optional(number)<br/> memory_gib_per_vcpu = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> memory_mib = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> network_bandwidth_gbps = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> network_interface_count = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> on_demand_max_price_percentage_over_lowest_price = optional(number)<br/> require_hibernate_support = optional(bool)<br/> spot_max_price_percentage_over_lowest_price = optional(number)<br/> total_local_storage_gb = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> vcpu_count = optional(object({<br/> max = optional(number)<br/> min = string<br/> }))<br/> })</pre> | `null` | no |
| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | The type of the instance to launch | `string` | `"m6i.large"` | no |
| <a name="input_kernel_id"></a> [kernel\_id](#input\_kernel\_id) | The kernel ID | `string` | `null` | no |
| <a name="input_key_name"></a> [key\_name](#input\_key\_name) | The key name that should be used for the instance | `string` | `null` | no |
| <a name="input_kubernetes_version"></a> [kubernetes\_version](#input\_kubernetes\_version) | Kubernetes cluster version - used to lookup default AMI ID if one is not provided | `string` | `null` | no |
| <a name="input_launch_template_default_version"></a> [launch\_template\_default\_version](#input\_launch\_template\_default\_version) | Default Version of the launch template | `string` | `null` | no |
| <a name="input_launch_template_description"></a> [launch\_template\_description](#input\_launch\_template\_description) | Description of the launch template | `string` | `null` | no |
| <a name="input_launch_template_id"></a> [launch\_template\_id](#input\_launch\_template\_id) | The ID of an existing launch template to use. Required when `create_launch_template` = `false` | `string` | `""` | no |
@@ -161,42 +157,42 @@ module "self_managed_node_group" {
| <a name="input_launch_template_tags"></a> [launch\_template\_tags](#input\_launch\_template\_tags) | A map of additional tags to add to the tag\_specifications of launch template created | `map(string)` | `{}` | no |
| <a name="input_launch_template_use_name_prefix"></a> [launch\_template\_use\_name\_prefix](#input\_launch\_template\_use\_name\_prefix) | Determines whether to use `launch_template_name` as is or create a unique name beginning with the `launch_template_name` as the prefix | `bool` | `true` | no |
| <a name="input_launch_template_version"></a> [launch\_template\_version](#input\_launch\_template\_version) | Launch template version. Can be version number, `$Latest`, or `$Default` | `string` | `null` | no |
| <a name="input_license_specifications"></a> [license\_specifications](#input\_license\_specifications) | A map of license specifications to associate with | `any` | `{}` | no |
| <a name="input_maintenance_options"></a> [maintenance\_options](#input\_maintenance\_options) | The maintenance options for the instance | `any` | `{}` | no |
| <a name="input_license_specifications"></a> [license\_specifications](#input\_license\_specifications) | A list of license specifications to associate with | <pre>list(object({<br/> license_configuration_arn = string<br/> }))</pre> | `null` | no |
| <a name="input_maintenance_options"></a> [maintenance\_options](#input\_maintenance\_options) | The maintenance options for the instance | <pre>object({<br/> auto_recovery = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_max_instance_lifetime"></a> [max\_instance\_lifetime](#input\_max\_instance\_lifetime) | The maximum amount of time, in seconds, that an instance can be in service, values must be either equal to 0 or between 604800 and 31536000 seconds | `number` | `null` | no |
| <a name="input_max_size"></a> [max\_size](#input\_max\_size) | The maximum size of the autoscaling group | `number` | `3` | no |
| <a name="input_metadata_options"></a> [metadata\_options](#input\_metadata\_options) | Customize the metadata options for the instance | `map(string)` | <pre>{<br/> "http_endpoint": "enabled",<br/> "http_put_response_hop_limit": 2,<br/> "http_tokens": "required"<br/>}</pre> | no |
| <a name="input_metadata_options"></a> [metadata\_options](#input\_metadata\_options) | Customize the metadata options for the instance | <pre>object({<br/> http_endpoint = optional(string, "enabled")<br/> http_protocol_ipv6 = optional(string)<br/> http_put_response_hop_limit = optional(number, 1)<br/> http_tokens = optional(string, "required")<br/> instance_metadata_tags = optional(string)<br/> })</pre> | <pre>{<br/> "http_endpoint": "enabled",<br/> "http_put_response_hop_limit": 1,<br/> "http_tokens": "required"<br/>}</pre> | no |
| <a name="input_metrics_granularity"></a> [metrics\_granularity](#input\_metrics\_granularity) | The granularity to associate with the metrics to collect. The only valid value is `1Minute` | `string` | `null` | no |
| <a name="input_min_elb_capacity"></a> [min\_elb\_capacity](#input\_min\_elb\_capacity) | Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes | `number` | `null` | no |
| <a name="input_min_size"></a> [min\_size](#input\_min\_size) | The minimum size of the autoscaling group | `number` | `0` | no |
| <a name="input_mixed_instances_policy"></a> [mixed\_instances\_policy](#input\_mixed\_instances\_policy) | Configuration block containing settings to define launch targets for Auto Scaling groups | `any` | `null` | no |
| <a name="input_min_size"></a> [min\_size](#input\_min\_size) | The minimum size of the autoscaling group | `number` | `1` | no |
| <a name="input_mixed_instances_policy"></a> [mixed\_instances\_policy](#input\_mixed\_instances\_policy) | Configuration block containing settings to define launch targets for Auto Scaling groups | <pre>object({<br/> instances_distribution = optional(object({<br/> on_demand_allocation_strategy = optional(string)<br/> on_demand_base_capacity = optional(number)<br/> on_demand_percentage_above_base_capacity = optional(number)<br/> spot_allocation_strategy = optional(string)<br/> spot_instance_pools = optional(number)<br/> spot_max_price = optional(string)<br/> }))<br/> launch_template = object({<br/> override = optional(list(object({<br/> instance_requirements = optional(object({<br/> accelerator_count = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> accelerator_manufacturers = optional(list(string))<br/> accelerator_names = optional(list(string))<br/> accelerator_total_memory_mib = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> accelerator_types = optional(list(string))<br/> allowed_instance_types = optional(list(string))<br/> bare_metal = optional(string)<br/> baseline_ebs_bandwidth_mbps = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> burstable_performance = optional(string)<br/> cpu_manufacturers = optional(list(string))<br/> excluded_instance_types = optional(list(string))<br/> instance_generations = optional(list(string))<br/> local_storage = optional(string)<br/> local_storage_types = optional(list(string))<br/> max_spot_price_as_percentage_of_optimal_on_demand_price = optional(number)<br/> memory_gib_per_vcpu = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> memory_mib = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> network_bandwidth_gbps = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> network_interface_count = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> on_demand_max_price_percentage_over_lowest_price = optional(number)<br/> require_hibernate_support = optional(bool)<br/> spot_max_price_percentage_over_lowest_price = optional(number)<br/> total_local_storage_gb = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> vcpu_count = optional(object({<br/> max = optional(number)<br/> min = optional(number)<br/> }))<br/> }))<br/> instance_type = optional(string)<br/> launch_template_specification = optional(object({<br/> launch_template_id = optional(string)<br/> launch_template_name = optional(string)<br/> version = optional(string)<br/> }))<br/> weighted_capacity = optional(string)<br/> })))<br/> })<br/> })</pre> | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | Name of the Self managed Node Group | `string` | `""` | no |
| <a name="input_network_interfaces"></a> [network\_interfaces](#input\_network\_interfaces) | Customize network interfaces to be attached at instance boot time | `list(any)` | `[]` | no |
| <a name="input_placement"></a> [placement](#input\_placement) | The placement of the instance | `map(string)` | `{}` | no |
| <a name="input_placement_group"></a> [placement\_group](#input\_placement\_group) | The name of the placement group into which you'll launch your instances, if any | `string` | `null` | no |
| <a name="input_placement_group_az"></a> [placement\_group\_az](#input\_placement\_group\_az) | Availability zone where placement group is created (ex. `eu-west-1c`) | `string` | `null` | no |
| <a name="input_platform"></a> [platform](#input\_platform) | [DEPRECATED - must use `ami_type` instead. Will be removed in `v21.0`] | `string` | `null` | no |
| <a name="input_post_bootstrap_user_data"></a> [post\_bootstrap\_user\_data](#input\_post\_bootstrap\_user\_data) | User data that is appended to the user data script after of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `""` | no |
| <a name="input_pre_bootstrap_user_data"></a> [pre\_bootstrap\_user\_data](#input\_pre\_bootstrap\_user\_data) | User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `""` | no |
| <a name="input_private_dns_name_options"></a> [private\_dns\_name\_options](#input\_private\_dns\_name\_options) | The options for the instance hostname. The default values are inherited from the subnet | `map(string)` | `{}` | no |
| <a name="input_protect_from_scale_in"></a> [protect\_from\_scale\_in](#input\_protect\_from\_scale\_in) | Allows setting instance protection. The autoscaling group will not select instances with this setting for termination during scale in events. | `bool` | `false` | no |
| <a name="input_network_interfaces"></a> [network\_interfaces](#input\_network\_interfaces) | Customize network interfaces to be attached at instance boot time | <pre>list(object({<br/> associate_carrier_ip_address = optional(bool)<br/> associate_public_ip_address = optional(bool)<br/> connection_tracking_specification = optional(object({<br/> tcp_established_timeout = optional(number)<br/> udp_stream_timeout = optional(number)<br/> udp_timeout = optional(number)<br/> }))<br/> delete_on_termination = optional(bool)<br/> description = optional(string)<br/> device_index = optional(number)<br/> ena_srd_specification = optional(object({<br/> ena_srd_enabled = optional(bool)<br/> ena_srd_udp_specification = optional(object({<br/> ena_srd_udp_enabled = optional(bool)<br/> }))<br/> }))<br/> interface_type = optional(string)<br/> ipv4_address_count = optional(number)<br/> ipv4_addresses = optional(list(string))<br/> ipv4_prefix_count = optional(number)<br/> ipv4_prefixes = optional(list(string))<br/> ipv6_address_count = optional(number)<br/> ipv6_addresses = optional(list(string))<br/> ipv6_prefix_count = optional(number)<br/> ipv6_prefixes = optional(list(string))<br/> network_card_index = optional(number)<br/> network_interface_id = optional(string)<br/> primary_ipv6 = optional(bool)<br/> private_ip_address = optional(string)<br/> security_groups = optional(list(string), [])<br/> subnet_id = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_partition"></a> [partition](#input\_partition) | The AWS partition - pass through value to reduce number of GET requests from data sources | `string` | `""` | no |
| <a name="input_placement"></a> [placement](#input\_placement) | The placement of the instance | <pre>object({<br/> affinity = optional(string)<br/> availability_zone = optional(string)<br/> group_name = optional(string)<br/> host_id = optional(string)<br/> host_resource_group_arn = optional(string)<br/> partition_number = optional(number)<br/> spread_domain = optional(string)<br/> tenancy = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_placement_group"></a> [placement\_group](#input\_placement\_group) | The name of the placement group into which you'll launch your instances | `string` | `null` | no |
| <a name="input_post_bootstrap_user_data"></a> [post\_bootstrap\_user\_data](#input\_post\_bootstrap\_user\_data) | User data that is appended to the user data script after of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `null` | no |
| <a name="input_pre_bootstrap_user_data"></a> [pre\_bootstrap\_user\_data](#input\_pre\_bootstrap\_user\_data) | User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*` | `string` | `null` | no |
| <a name="input_private_dns_name_options"></a> [private\_dns\_name\_options](#input\_private\_dns\_name\_options) | The options for the instance hostname. The default values are inherited from the subnet | <pre>object({<br/> enable_resource_name_dns_aaaa_record = optional(bool)<br/> enable_resource_name_dns_a_record = optional(bool)<br/> hostname_type = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_protect_from_scale_in"></a> [protect\_from\_scale\_in](#input\_protect\_from\_scale\_in) | Allows setting instance protection. The autoscaling group will not select instances with this setting for termination during scale in events | `bool` | `false` | no |
| <a name="input_ram_disk_id"></a> [ram\_disk\_id](#input\_ram\_disk\_id) | The ID of the ram disk | `string` | `null` | no |
| <a name="input_schedules"></a> [schedules](#input\_schedules) | Map of autoscaling group schedule to create | `map(any)` | `{}` | no |
| <a name="input_service_linked_role_arn"></a> [service\_linked\_role\_arn](#input\_service\_linked\_role\_arn) | The ARN of the service-linked role that the ASG will use to call other AWS services | `string` | `null` | no |
| <a name="input_region"></a> [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no |
| <a name="input_security_group_description"></a> [security\_group\_description](#input\_security\_group\_description) | Description of the security group created | `string` | `null` | no |
| <a name="input_security_group_egress_rules"></a> [security\_group\_egress\_rules](#input\_security\_group\_egress\_rules) | Security group egress rules to add to the security group created | <pre>map(object({<br/> name = optional(string)<br/><br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(string)<br/> ip_protocol = optional(string, "tcp")<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> self = optional(bool, false)<br/> tags = optional(map(string), {})<br/> to_port = optional(string)<br/> }))</pre> | `{}` | no |
| <a name="input_security_group_ingress_rules"></a> [security\_group\_ingress\_rules](#input\_security\_group\_ingress\_rules) | Security group ingress rules to add to the security group created | <pre>map(object({<br/> name = optional(string)<br/><br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(string)<br/> ip_protocol = optional(string, "tcp")<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> self = optional(bool, false)<br/> tags = optional(map(string), {})<br/> to_port = optional(string)<br/> }))</pre> | `{}` | no |
| <a name="input_security_group_name"></a> [security\_group\_name](#input\_security\_group\_name) | Name to use on security group created | `string` | `null` | no |
| <a name="input_security_group_tags"></a> [security\_group\_tags](#input\_security\_group\_tags) | A map of additional tags to add to the security group created | `map(string)` | `{}` | no |
| <a name="input_security_group_use_name_prefix"></a> [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`security_group_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs to launch resources in. Subnets automatically determine which availability zones the group will reside. Conflicts with `availability_zones` | `list(string)` | `null` | no |
| <a name="input_suspended_processes"></a> [suspended\_processes](#input\_suspended\_processes) | A list of processes to suspend for the Auto Scaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your Auto Scaling Group from functioning properly | `list(string)` | `[]` | no |
| <a name="input_tag_specifications"></a> [tag\_specifications](#input\_tag\_specifications) | The tags to apply to the resources during launch | `list(string)` | <pre>[<br/> "instance",<br/> "volume",<br/> "network-interface"<br/>]</pre> | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
| <a name="input_target_group_arns"></a> [target\_group\_arns](#input\_target\_group\_arns) | A set of `aws_alb_target_group` ARNs, for use with Application or Network Load Balancing | `list(string)` | `[]` | no |
| <a name="input_termination_policies"></a> [termination\_policies](#input\_termination\_policies) | A list of policies to decide how the instances in the Auto Scaling Group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `OldestLaunchTemplate`, `AllocationStrategy`, `Default` | `list(string)` | `[]` | no |
| <a name="input_timeouts"></a> [timeouts](#input\_timeouts) | Timeout configurations for the autoscaling group | <pre>object({<br/> delete = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_update_launch_template_default_version"></a> [update\_launch\_template\_default\_version](#input\_update\_launch\_template\_default\_version) | Whether to update Default Version each update. Conflicts with `launch_template_default_version` | `bool` | `true` | no |
| <a name="input_use_mixed_instances_policy"></a> [use\_mixed\_instances\_policy](#input\_use\_mixed\_instances\_policy) | Determines whether to use a mixed instances policy in the autoscaling group or not | `bool` | `false` | no |
| <a name="input_use_name_prefix"></a> [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix | `bool` | `true` | no |
| <a name="input_user_data_template_path"></a> [user\_data\_template\_path](#input\_user\_data\_template\_path) | Path to a local, custom user data template file to use when rendering user data | `string` | `""` | no |
| <a name="input_user_data_template_path"></a> [user\_data\_template\_path](#input\_user\_data\_template\_path) | Path to a local, custom user data template file to use when rendering user data | `string` | `null` | no |
| <a name="input_vpc_security_group_ids"></a> [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | A list of security group IDs to associate | `list(string)` | `[]` | no |
| <a name="input_wait_for_capacity_timeout"></a> [wait\_for\_capacity\_timeout](#input\_wait\_for\_capacity\_timeout) | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. (See also Waiting for Capacity below.) Setting this to '0' causes Terraform to skip all Capacity Waiting behavior. | `string` | `null` | no |
| <a name="input_wait_for_elb_capacity"></a> [wait\_for\_elb\_capacity](#input\_wait\_for\_elb\_capacity) | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior. | `number` | `null` | no |
| <a name="input_warm_pool"></a> [warm\_pool](#input\_warm\_pool) | If this block is configured, add a Warm Pool to the specified Auto Scaling group | `any` | `{}` | no |
## Outputs
@@ -213,7 +209,6 @@ module "self_managed_node_group" {
| <a name="output_autoscaling_group_max_size"></a> [autoscaling\_group\_max\_size](#output\_autoscaling\_group\_max\_size) | The maximum size of the autoscaling group |
| <a name="output_autoscaling_group_min_size"></a> [autoscaling\_group\_min\_size](#output\_autoscaling\_group\_min\_size) | The minimum size of the autoscaling group |
| <a name="output_autoscaling_group_name"></a> [autoscaling\_group\_name](#output\_autoscaling\_group\_name) | The autoscaling group name |
| <a name="output_autoscaling_group_schedule_arns"></a> [autoscaling\_group\_schedule\_arns](#output\_autoscaling\_group\_schedule\_arns) | ARNs of autoscaling group schedules |
| <a name="output_autoscaling_group_vpc_zone_identifier"></a> [autoscaling\_group\_vpc\_zone\_identifier](#output\_autoscaling\_group\_vpc\_zone\_identifier) | The VPC zone identifier |
| <a name="output_iam_instance_profile_arn"></a> [iam\_instance\_profile\_arn](#output\_iam\_instance\_profile\_arn) | ARN assigned by AWS to the instance profile |
| <a name="output_iam_instance_profile_id"></a> [iam\_instance\_profile\_id](#output\_iam\_instance\_profile\_id) | Instance profile's ID |
@@ -226,6 +221,7 @@ module "self_managed_node_group" {
| <a name="output_launch_template_id"></a> [launch\_template\_id](#output\_launch\_template\_id) | The ID of the launch template |
| <a name="output_launch_template_latest_version"></a> [launch\_template\_latest\_version](#output\_launch\_template\_latest\_version) | The latest version of the launch template |
| <a name="output_launch_template_name"></a> [launch\_template\_name](#output\_launch\_template\_name) | The name of the launch template |
| <a name="output_platform"></a> [platform](#output\_platform) | [DEPRECATED - Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023`, or `windows` |
| <a name="output_security_group_arn"></a> [security\_group\_arn](#output\_security\_group\_arn) | Amazon Resource Name (ARN) of the security group |
| <a name="output_security_group_id"></a> [security\_group\_id](#output\_security\_group\_id) | ID of the security group |
| <a name="output_user_data"></a> [user\_data](#output\_user\_data) | Base64 encoded user data |
<!-- END_TF_DOCS -->
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -128,24 +128,10 @@ output "access_entry_arn" {
value = try(aws_eks_access_entry.this[0].access_entry_arn, null)
}
################################################################################
# Autoscaling Group Schedule
################################################################################
output "autoscaling_group_schedule_arns" {
description = "ARNs of autoscaling group schedules"
value = { for k, v in aws_autoscaling_schedule.this : k => v.arn }
}
################################################################################
# Additional
################################################################################
output "platform" {
description = "[DEPRECATED - Will be removed in `v21.0`] Identifies the OS platform as `bottlerocket`, `linux` (AL2), `al2023`, or `windows`"
value = module.user_data.platform
}
output "image_id" {
description = "ID of the image"
value = try(aws_launch_template.this[0].image_id, null)
@@ -155,3 +141,17 @@ output "user_data" {
description = "Base64 encoded user data"
value = try(module.user_data.user_data, null)
}
################################################################################
# Security Group
################################################################################
output "security_group_arn" {
description = "Amazon Resource Name (ARN) of the security group"
value = try(aws_security_group.this[0].arn, null)
}
output "security_group_id" {
description = "ID of the security group"
value = try(aws_security_group.this[0].id, null)
}
+443 -145
View File
@@ -2,6 +2,7 @@ variable "create" {
description = "Determines whether to create self managed node group or not"
type = bool
default = true
nullable = false
}
variable "tags" {
@@ -10,16 +11,22 @@ variable "tags" {
default = {}
}
# tflint-ignore: terraform_unused_declarations
variable "platform" {
description = "[DEPRECATED - must use `ami_type` instead. Will be removed in `v21.0`]"
variable "region" {
description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration"
type = string
default = null
}
validation {
condition = var.platform == null
error_message = "`platform` is no longer valid due to the number of OS choices. Please provide an [`ami_type`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-amitype) instead."
}
variable "partition" {
description = "The AWS partition - pass through value to reduce number of GET requests from data sources"
type = string
default = ""
}
variable "account_id" {
description = "The AWS account ID - pass through value to reduce number of GET requests from data sources"
type = string
default = ""
}
################################################################################
@@ -35,55 +42,55 @@ variable "cluster_name" {
variable "cluster_endpoint" {
description = "Endpoint of associated EKS cluster"
type = string
default = ""
default = null
}
variable "cluster_auth_base64" {
description = "Base64 encoded CA of associated EKS cluster"
type = string
default = ""
default = null
}
variable "cluster_service_cidr" {
description = "The CIDR block (IPv4 or IPv6) used by the cluster to assign Kubernetes service IP addresses. This is derived from the cluster itself"
type = string
default = ""
default = null
}
variable "cluster_ip_family" {
description = "The IP family used to assign Kubernetes pod and service addresses. Valid values are `ipv4` (default) and `ipv6`"
type = string
default = "ipv4"
default = null
}
variable "additional_cluster_dns_ips" {
description = "Additional DNS IP addresses to use for the cluster. Only used when `ami_type` = `BOTTLEROCKET_*`"
type = list(string)
default = []
default = null
}
variable "pre_bootstrap_user_data" {
description = "User data that is injected into the user data script ahead of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*`"
type = string
default = ""
default = null
}
variable "post_bootstrap_user_data" {
description = "User data that is appended to the user data script after of the EKS bootstrap script. Not used when `ami_type` = `BOTTLEROCKET_*`"
type = string
default = ""
default = null
}
variable "bootstrap_extra_args" {
description = "Additional arguments passed to the bootstrap script. When `ami_type` = `BOTTLEROCKET_*`; these are additional [settings](https://github.com/bottlerocket-os/bottlerocket#settings) that are provided to the Bottlerocket user data"
type = string
default = ""
default = null
}
variable "user_data_template_path" {
description = "Path to a local, custom user data template file to use when rendering user data"
type = string
default = ""
default = null
}
variable "cloudinit_pre_nodeadm" {
@@ -94,7 +101,7 @@ variable "cloudinit_pre_nodeadm" {
filename = optional(string)
merge_type = optional(string)
}))
default = []
default = null
}
variable "cloudinit_post_nodeadm" {
@@ -105,7 +112,7 @@ variable "cloudinit_post_nodeadm" {
filename = optional(string)
merge_type = optional(string)
}))
default = []
default = null
}
################################################################################
@@ -116,6 +123,7 @@ variable "create_launch_template" {
description = "Determines whether to create launch template or not"
type = bool
default = true
nullable = false
}
variable "launch_template_id" {
@@ -134,6 +142,7 @@ variable "launch_template_use_name_prefix" {
description = "Determines whether to use `launch_template_name` as is or create a unique name beginning with the `launch_template_name` as the prefix"
type = bool
default = true
nullable = false
}
variable "launch_template_description" {
@@ -152,6 +161,7 @@ variable "update_launch_template_default_version" {
description = "Whether to update Default Version each update. Conflicts with `launch_template_default_version`"
type = bool
default = true
nullable = false
}
variable "disable_api_termination" {
@@ -180,92 +190,163 @@ variable "ram_disk_id" {
variable "block_device_mappings" {
description = "Specify volumes to attach to the instance besides the volumes specified by the AMI"
type = any
default = {}
type = map(object({
device_name = optional(string)
ebs = optional(object({
delete_on_termination = optional(bool)
encrypted = optional(bool)
iops = optional(number)
kms_key_id = optional(string)
snapshot_id = optional(string)
throughput = optional(number)
volume_initialization_rate = optional(number)
volume_size = optional(number)
volume_type = optional(string)
}))
no_device = optional(string)
virtual_name = optional(string)
}))
default = null
}
variable "capacity_reservation_specification" {
description = "Targeting for EC2 capacity reservations"
type = any
default = {}
type = object({
capacity_reservation_preference = optional(string)
capacity_reservation_target = optional(object({
capacity_reservation_id = optional(string)
capacity_reservation_resource_group_arn = optional(string)
}))
})
default = null
}
variable "cpu_options" {
description = "The CPU options for the instance"
type = map(string)
default = {}
type = object({
amd_sev_snp = optional(string)
core_count = optional(number)
threads_per_core = optional(number)
})
default = null
}
variable "credit_specification" {
description = "Customize the credit specification of the instance"
type = map(string)
default = {}
}
variable "elastic_gpu_specifications" {
description = "The elastic GPU to attach to the instance"
type = any
default = {}
}
variable "elastic_inference_accelerator" {
description = "Configuration block containing an Elastic Inference Accelerator to attach to the instance"
type = map(string)
default = {}
type = object({
cpu_credits = optional(string)
})
default = null
}
variable "enclave_options" {
description = "Enable Nitro Enclaves on launched instances"
type = map(string)
default = {}
}
variable "hibernation_options" {
description = "The hibernation options for the instance"
type = map(string)
default = {}
type = object({
enabled = optional(bool)
})
default = null
}
variable "instance_market_options" {
description = "The market (purchasing) option for the instance"
type = any
default = {}
type = object({
market_type = optional(string)
spot_options = optional(object({
block_duration_minutes = optional(number)
instance_interruption_behavior = optional(string)
max_price = optional(string)
spot_instance_type = optional(string)
valid_until = optional(string)
}))
})
default = null
}
variable "maintenance_options" {
description = "The maintenance options for the instance"
type = any
default = {}
type = object({
auto_recovery = optional(string)
})
default = null
}
variable "license_specifications" {
description = "A map of license specifications to associate with"
type = any
default = {}
description = "A list of license specifications to associate with"
type = list(object({
license_configuration_arn = string
}))
default = null
}
variable "network_interfaces" {
description = "Customize network interfaces to be attached at instance boot time"
type = list(any)
type = list(object({
associate_carrier_ip_address = optional(bool)
associate_public_ip_address = optional(bool)
connection_tracking_specification = optional(object({
tcp_established_timeout = optional(number)
udp_stream_timeout = optional(number)
udp_timeout = optional(number)
}))
delete_on_termination = optional(bool)
description = optional(string)
device_index = optional(number)
ena_srd_specification = optional(object({
ena_srd_enabled = optional(bool)
ena_srd_udp_specification = optional(object({
ena_srd_udp_enabled = optional(bool)
}))
}))
interface_type = optional(string)
ipv4_address_count = optional(number)
ipv4_addresses = optional(list(string))
ipv4_prefix_count = optional(number)
ipv4_prefixes = optional(list(string))
ipv6_address_count = optional(number)
ipv6_addresses = optional(list(string))
ipv6_prefix_count = optional(number)
ipv6_prefixes = optional(list(string))
network_card_index = optional(number)
network_interface_id = optional(string)
primary_ipv6 = optional(bool)
private_ip_address = optional(string)
security_groups = optional(list(string), [])
subnet_id = optional(string)
}))
default = []
nullable = false
}
variable "placement" {
description = "The placement of the instance"
type = map(string)
default = {}
type = object({
affinity = optional(string)
availability_zone = optional(string)
group_name = optional(string)
host_id = optional(string)
host_resource_group_arn = optional(string)
partition_number = optional(number)
spread_domain = optional(string)
tenancy = optional(string)
})
default = null
}
variable "create_placement_group" {
description = "Determines whether a placement group is created & used by the node group"
type = bool
default = false
nullable = false
}
variable "private_dns_name_options" {
description = "The options for the instance hostname. The default values are inherited from the subnet"
type = map(string)
default = {}
type = object({
enable_resource_name_dns_aaaa_record = optional(bool)
enable_resource_name_dns_a_record = optional(bool)
hostname_type = optional(string)
})
default = null
}
variable "ebs_optimized" {
@@ -283,10 +364,11 @@ variable "ami_id" {
variable "ami_type" {
description = "Type of Amazon Machine Image (AMI) associated with the node group. See the [AWS documentation](https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html#AmazonEKS-Type-Nodegroup-amiType) for valid values"
type = string
default = "AL2_x86_64"
default = "AL2023_x86_64_STANDARD"
nullable = false
}
variable "cluster_version" {
variable "kubernetes_version" {
description = "Kubernetes cluster version - used to lookup default AMI ID if one is not provided"
type = string
default = null
@@ -294,14 +376,67 @@ variable "cluster_version" {
variable "instance_requirements" {
description = "The attribute requirements for the type of instance. If present then `instance_type` cannot be present"
type = any
default = {}
type = object({
accelerator_count = optional(object({
max = optional(number)
min = optional(number)
}))
accelerator_manufacturers = optional(list(string))
accelerator_names = optional(list(string))
accelerator_total_memory_mib = optional(object({
max = optional(number)
min = optional(number)
}))
accelerator_types = optional(list(string))
allowed_instance_types = optional(list(string))
bare_metal = optional(string)
baseline_ebs_bandwidth_mbps = optional(object({
max = optional(number)
min = optional(number)
}))
burstable_performance = optional(string)
cpu_manufacturers = optional(list(string))
excluded_instance_types = optional(list(string))
instance_generations = optional(list(string))
local_storage = optional(string)
local_storage_types = optional(list(string))
max_spot_price_as_percentage_of_optimal_on_demand_price = optional(number)
memory_gib_per_vcpu = optional(object({
max = optional(number)
min = optional(number)
}))
memory_mib = optional(object({
max = optional(number)
min = optional(number)
}))
network_bandwidth_gbps = optional(object({
max = optional(number)
min = optional(number)
}))
network_interface_count = optional(object({
max = optional(number)
min = optional(number)
}))
on_demand_max_price_percentage_over_lowest_price = optional(number)
require_hibernate_support = optional(bool)
spot_max_price_percentage_over_lowest_price = optional(number)
total_local_storage_gb = optional(object({
max = optional(number)
min = optional(number)
}))
vcpu_count = optional(object({
max = optional(number)
min = string
}))
})
default = null
}
variable "instance_type" {
description = "The type of the instance to launch"
type = string
default = ""
default = "m6i.large"
nullable = false
}
variable "key_name" {
@@ -314,6 +449,7 @@ variable "vpc_security_group_ids" {
description = "A list of security group IDs to associate"
type = list(string)
default = []
nullable = false
}
variable "cluster_primary_security_group_id" {
@@ -325,48 +461,60 @@ variable "cluster_primary_security_group_id" {
variable "enable_monitoring" {
description = "Enables/disables detailed monitoring"
type = bool
default = true
default = false
nullable = false
}
variable "enable_efa_support" {
description = "Determines whether to enable Elastic Fabric Adapter (EFA) support"
type = bool
default = false
nullable = false
}
# TODO - make this true by default at next breaking change (remove variable, only pass indices)
variable "enable_efa_only" {
description = "Determines whether to enable EFA (`false`, default) or EFA and EFA-only (`true`) network interfaces. Note: requires vpc-cni version `v1.18.4` or later"
type = bool
default = false
default = true
nullable = false
}
variable "efa_indices" {
description = "The indices of the network interfaces that should be EFA-enabled. Only valid when `enable_efa_support` = `true`"
type = list(number)
default = [0]
nullable = false
}
variable "metadata_options" {
description = "Customize the metadata options for the instance"
type = map(string)
type = object({
http_endpoint = optional(string, "enabled")
http_protocol_ipv6 = optional(string)
http_put_response_hop_limit = optional(number, 1)
http_tokens = optional(string, "required")
instance_metadata_tags = optional(string)
})
default = {
http_endpoint = "enabled"
http_put_response_hop_limit = 1
http_tokens = "required"
http_put_response_hop_limit = 2
}
nullable = false
}
variable "launch_template_tags" {
description = "A map of additional tags to add to the tag_specifications of launch template created"
type = map(string)
default = {}
nullable = false
}
variable "tag_specifications" {
description = "The tags to apply to the resources during launch"
type = list(string)
default = ["instance", "volume", "network-interface"]
nullable = false
}
################################################################################
@@ -377,6 +525,7 @@ variable "create_autoscaling_group" {
description = "Determines whether to create autoscaling group or not"
type = bool
default = true
nullable = false
}
variable "name" {
@@ -389,6 +538,7 @@ variable "use_name_prefix" {
description = "Determines whether to use `name` as is or create a unique name beginning with the `name` as the prefix"
type = bool
default = true
nullable = false
}
variable "launch_template_version" {
@@ -403,12 +553,6 @@ variable "availability_zones" {
default = null
}
variable "placement_group_az" {
description = "Availability zone where placement group is created (ex. `eu-west-1c`)"
type = string
default = null
}
variable "subnet_ids" {
description = "A list of subnet IDs to launch resources in. Subnets automatically determine which availability zones the group will reside. Conflicts with `availability_zones`"
type = list(string)
@@ -418,19 +562,22 @@ variable "subnet_ids" {
variable "min_size" {
description = "The minimum size of the autoscaling group"
type = number
default = 0
default = 1
nullable = false
}
variable "max_size" {
description = "The maximum size of the autoscaling group"
type = number
default = 3
nullable = false
}
variable "desired_size" {
description = "The number of Amazon EC2 instances that should be running in the autoscaling group"
type = number
default = 1
nullable = false
}
variable "desired_size_type" {
@@ -440,7 +587,7 @@ variable "desired_size_type" {
}
variable "ignore_failed_scaling_activities" {
description = "Whether to ignore failed Auto Scaling scaling activities while waiting for capacity."
description = "Whether to ignore failed Auto Scaling scaling activities while waiting for capacity"
type = bool
default = null
}
@@ -457,30 +604,6 @@ variable "capacity_rebalance" {
default = null
}
variable "min_elb_capacity" {
description = "Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes"
type = number
default = null
}
variable "wait_for_elb_capacity" {
description = "Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior."
type = number
default = null
}
variable "wait_for_capacity_timeout" {
description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. (See also Waiting for Capacity below.) Setting this to '0' causes Terraform to skip all Capacity Waiting behavior."
type = string
default = null
}
variable "default_cooldown" {
description = "The amount of time, in seconds, after a scaling activity completes before another scaling activity can start"
type = number
default = null
}
variable "default_instance_warmup" {
description = "Amount of time, in seconds, until a newly launched instance can contribute to the Amazon CloudWatch metrics. This delay lets an instance finish initializing before Amazon EC2 Auto Scaling aggregates instance metrics, resulting in more reliable usage data"
type = number
@@ -488,19 +611,14 @@ variable "default_instance_warmup" {
}
variable "protect_from_scale_in" {
description = "Allows setting instance protection. The autoscaling group will not select instances with this setting for termination during scale in events."
description = "Allows setting instance protection. The autoscaling group will not select instances with this setting for termination during scale in events"
type = bool
default = false
}
variable "target_group_arns" {
description = "A set of `aws_alb_target_group` ARNs, for use with Application or Network Load Balancing"
type = list(string)
default = []
nullable = false
}
variable "placement_group" {
description = "The name of the placement group into which you'll launch your instances, if any"
description = "The name of the placement group into which you'll launch your instances"
type = string
default = null
}
@@ -523,22 +641,18 @@ variable "force_delete" {
default = null
}
variable "force_delete_warm_pool" {
description = "Allows deleting the Auto Scaling Group without waiting for all instances in the warm pool to terminate"
type = bool
default = null
}
variable "termination_policies" {
description = "A list of policies to decide how the instances in the Auto Scaling Group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `OldestLaunchTemplate`, `AllocationStrategy`, `Default`"
type = list(string)
default = []
nullable = false
}
variable "suspended_processes" {
description = "A list of processes to suspend for the Auto Scaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your Auto Scaling Group from functioning properly"
type = list(string)
default = []
nullable = false
}
variable "max_instance_lifetime" {
@@ -551,6 +665,7 @@ variable "enabled_metrics" {
description = "A list of metrics to collect. The allowed values are `GroupDesiredCapacity`, `GroupInServiceCapacity`, `GroupPendingCapacity`, `GroupMinSize`, `GroupMaxSize`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupStandbyCapacity`, `GroupTerminatingCapacity`, `GroupTerminatingInstances`, `GroupTotalCapacity`, `GroupTotalInstances`"
type = list(string)
default = []
nullable = false
}
variable "metrics_granularity" {
@@ -559,56 +674,149 @@ variable "metrics_granularity" {
default = null
}
variable "service_linked_role_arn" {
description = "The ARN of the service-linked role that the ASG will use to call other AWS services"
type = string
default = null
}
variable "initial_lifecycle_hooks" {
description = "One or more Lifecycle Hooks to attach to the Auto Scaling Group before instances are launched. The syntax is exactly the same as the separate `aws_autoscaling_lifecycle_hook` resource, without the `autoscaling_group_name` attribute. Please note that this will only work when creating a new Auto Scaling Group. For all other use-cases, please use `aws_autoscaling_lifecycle_hook` resource"
type = list(map(string))
default = []
type = list(object({
default_result = optional(string)
heartbeat_timeout = optional(number)
lifecycle_transition = string
name = string
notification_metadata = optional(string)
notification_target_arn = optional(string)
role_arn = optional(string)
}))
default = null
}
variable "instance_maintenance_policy" {
description = "If this block is configured, add a instance maintenance policy to the specified Auto Scaling group"
type = any
default = {}
type = object({
max_healthy_percentage = number
min_healthy_percentage = number
})
default = null
}
variable "instance_refresh" {
description = "If this block is configured, start an Instance Refresh when this Auto Scaling Group is updated"
type = any
type = object({
preferences = optional(object({
alarm_specification = optional(object({
alarms = optional(list(string))
}))
auto_rollback = optional(bool)
checkpoint_delay = optional(number)
checkpoint_percentages = optional(list(number))
instance_warmup = optional(number)
max_healthy_percentage = optional(number)
min_healthy_percentage = optional(number, 33)
scale_in_protected_instances = optional(string)
skip_matching = optional(bool)
standby_instances = optional(string)
}))
strategy = optional(string, "Rolling")
triggers = optional(list(string))
})
default = {
strategy = "Rolling"
preferences = {
min_healthy_percentage = 66
}
}
nullable = false
}
variable "use_mixed_instances_policy" {
description = "Determines whether to use a mixed instances policy in the autoscaling group or not"
type = bool
default = false
nullable = false
}
variable "mixed_instances_policy" {
description = "Configuration block containing settings to define launch targets for Auto Scaling groups"
type = any
type = object({
instances_distribution = optional(object({
on_demand_allocation_strategy = optional(string)
on_demand_base_capacity = optional(number)
on_demand_percentage_above_base_capacity = optional(number)
spot_allocation_strategy = optional(string)
spot_instance_pools = optional(number)
spot_max_price = optional(string)
}))
launch_template = object({
override = optional(list(object({
instance_requirements = optional(object({
accelerator_count = optional(object({
max = optional(number)
min = optional(number)
}))
accelerator_manufacturers = optional(list(string))
accelerator_names = optional(list(string))
accelerator_total_memory_mib = optional(object({
max = optional(number)
min = optional(number)
}))
accelerator_types = optional(list(string))
allowed_instance_types = optional(list(string))
bare_metal = optional(string)
baseline_ebs_bandwidth_mbps = optional(object({
max = optional(number)
min = optional(number)
}))
burstable_performance = optional(string)
cpu_manufacturers = optional(list(string))
excluded_instance_types = optional(list(string))
instance_generations = optional(list(string))
local_storage = optional(string)
local_storage_types = optional(list(string))
max_spot_price_as_percentage_of_optimal_on_demand_price = optional(number)
memory_gib_per_vcpu = optional(object({
max = optional(number)
min = optional(number)
}))
memory_mib = optional(object({
max = optional(number)
min = optional(number)
}))
network_bandwidth_gbps = optional(object({
max = optional(number)
min = optional(number)
}))
network_interface_count = optional(object({
max = optional(number)
min = optional(number)
}))
on_demand_max_price_percentage_over_lowest_price = optional(number)
require_hibernate_support = optional(bool)
spot_max_price_percentage_over_lowest_price = optional(number)
total_local_storage_gb = optional(object({
max = optional(number)
min = optional(number)
}))
vcpu_count = optional(object({
max = optional(number)
min = optional(number)
}))
}))
instance_type = optional(string)
launch_template_specification = optional(object({
launch_template_id = optional(string)
launch_template_name = optional(string)
version = optional(string)
}))
weighted_capacity = optional(string)
})))
})
})
default = null
}
variable "warm_pool" {
description = "If this block is configured, add a Warm Pool to the specified Auto Scaling group"
type = any
default = {}
}
variable "delete_timeout" {
description = "Delete timeout to wait for destroying autoscaling group"
type = string
variable "timeouts" {
description = "Timeout configurations for the autoscaling group"
type = object({
delete = optional(string)
})
default = null
}
@@ -616,6 +824,7 @@ variable "autoscaling_group_tags" {
description = "A map of additional tags to add to the autoscaling group created. Tags are applied to the autoscaling group only and are NOT propagated to instances"
type = map(string)
default = {}
nullable = false
}
################################################################################
@@ -626,6 +835,7 @@ variable "create_iam_instance_profile" {
description = "Determines whether an IAM instance profile is created or to use an existing IAM instance profile"
type = bool
default = true
nullable = false
}
variable "iam_instance_profile_arn" {
@@ -644,6 +854,7 @@ variable "iam_role_use_name_prefix" {
description = "Determines whether cluster IAM role name (`iam_role_name`) is used as a prefix"
type = bool
default = true
nullable = false
}
variable "iam_role_path" {
@@ -655,7 +866,8 @@ variable "iam_role_path" {
variable "iam_role_description" {
description = "Description of the role"
type = string
default = null
default = "Self managed node group IAM role"
nullable = false
}
variable "iam_role_permissions_boundary" {
@@ -668,18 +880,21 @@ variable "iam_role_attach_cni_policy" {
description = "Whether to attach the `AmazonEKS_CNI_Policy`/`AmazonEKS_CNI_IPv6_Policy` IAM policy to the IAM IAM role. WARNING: If set `false` the permissions must be assigned to the `aws-node` DaemonSet pods via another method or nodes will not be able to join the cluster"
type = bool
default = true
nullable = false
}
variable "iam_role_additional_policies" {
description = "Additional policies to be added to the IAM role"
type = map(string)
default = {}
nullable = false
}
variable "iam_role_tags" {
description = "A map of additional tags to add to the IAM role created"
type = map(string)
default = {}
nullable = false
}
################################################################################
@@ -690,12 +905,33 @@ variable "create_iam_role_policy" {
description = "Determines whether an IAM role policy is created or not"
type = bool
default = true
nullable = false
}
variable "iam_role_policy_statements" {
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
type = any
default = []
type = list(object({
sid = optional(string)
actions = optional(list(string))
not_actions = optional(list(string))
effect = optional(string)
resources = optional(list(string))
not_resources = optional(list(string))
principals = optional(list(object({
type = string
identifiers = list(string)
})))
not_principals = optional(list(object({
type = string
identifiers = list(string)
})))
condition = optional(list(object({
test = string
values = list(string)
variable = string
})))
}))
default = null
}
################################################################################
@@ -706,6 +942,7 @@ variable "create_access_entry" {
description = "Determines whether an access entry is created for the IAM role used by the node group"
type = bool
default = true
nullable = false
}
variable "iam_role_arn" {
@@ -715,17 +952,78 @@ variable "iam_role_arn" {
}
################################################################################
# Autoscaling group schedule
# Security Group
################################################################################
variable "create_schedule" {
description = "Determines whether to create autoscaling group schedule or not"
variable "create_security_group" {
description = "Determines if a security group is created"
type = bool
default = true
nullable = false
}
variable "schedules" {
description = "Map of autoscaling group schedule to create"
type = map(any)
default = {}
variable "security_group_name" {
description = "Name to use on security group created"
type = string
default = null
}
variable "security_group_use_name_prefix" {
description = "Determines whether the security group name (`security_group_name`) is used as a prefix"
type = bool
default = true
nullable = false
}
variable "security_group_description" {
description = "Description of the security group created"
type = string
default = null
}
variable "security_group_ingress_rules" {
description = "Security group ingress rules to add to the security group created"
type = map(object({
name = optional(string)
cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(string)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
self = optional(bool, false)
tags = optional(map(string), {})
to_port = optional(string)
}))
default = {}
nullable = false
}
variable "security_group_egress_rules" {
description = "Security group egress rules to add to the security group created"
type = map(object({
name = optional(string)
cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(string)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
self = optional(bool, false)
tags = optional(map(string), {})
to_port = optional(string)
}))
default = {}
nullable = false
}
variable "security_group_tags" {
description = "A map of additional tags to add to the security group created"
type = map(string)
default = {}
nullable = false
}
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+262 -295
View File
@@ -1,23 +1,4 @@
locals {
metadata_options = {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 2
}
# EKS managed node group
default_update_config = {
max_unavailable_percentage = 33
}
# Self-managed node group
default_instance_refresh = {
strategy = "Rolling"
preferences = {
min_healthy_percentage = 66
}
}
kubernetes_network_config = try(aws_eks_cluster.this[0].kubernetes_network_config[0], {})
}
@@ -32,12 +13,12 @@ resource "time_sleep" "this" {
create_duration = var.dataplane_wait_duration
triggers = {
cluster_name = aws_eks_cluster.this[0].id
cluster_endpoint = aws_eks_cluster.this[0].endpoint
cluster_version = aws_eks_cluster.this[0].version
cluster_service_cidr = var.cluster_ip_family == "ipv6" ? try(local.kubernetes_network_config.service_ipv6_cidr, "") : try(local.kubernetes_network_config.service_ipv4_cidr, "")
name = aws_eks_cluster.this[0].id
endpoint = aws_eks_cluster.this[0].endpoint
kubernetes_version = aws_eks_cluster.this[0].version
service_cidr = var.ip_family == "ipv6" ? try(local.kubernetes_network_config.service_ipv6_cidr, "") : try(local.kubernetes_network_config.service_ipv4_cidr, "")
cluster_certificate_authority_data = aws_eks_cluster.this[0].certificate_authority[0].data
certificate_authority_data = aws_eks_cluster.this[0].certificate_authority[0].data
}
}
@@ -87,7 +68,7 @@ resource "aws_iam_policy" "cni_ipv6_policy" {
################################################################################
locals {
node_sg_name = coalesce(var.node_security_group_name, "${var.cluster_name}-node")
node_sg_name = coalesce(var.node_security_group_name, "${var.name}-node")
create_node_sg = var.create && var.create_node_security_group
node_security_group_id = local.create_node_sg ? aws_security_group.node[0].id : var.node_security_group_id
@@ -179,35 +160,16 @@ locals {
to_port = 0
type = "egress"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = var.cluster_ip_family == "ipv6" ? ["::/0"] : null
ipv6_cidr_blocks = var.ip_family == "ipv6" ? ["::/0"] : null
}
} : k => v if var.node_security_group_enable_recommended_rules }
efa_security_group_rules = { for k, v in
{
ingress_all_self_efa = {
description = "Node to node EFA"
protocol = "-1"
from_port = 0
to_port = 0
type = "ingress"
self = true
}
egress_all_self_efa = {
description = "Node to node EFA"
protocol = "-1"
from_port = 0
to_port = 0
type = "egress"
self = true
}
} : k => v if var.enable_efa_support
}
}
resource "aws_security_group" "node" {
count = local.create_node_sg ? 1 : 0
region = var.region
name = var.node_security_group_use_name_prefix ? null : local.node_sg_name
name_prefix = var.node_security_group_use_name_prefix ? "${local.node_sg_name}${var.prefix_separator}" : null
description = var.node_security_group_description
@@ -217,7 +179,7 @@ resource "aws_security_group" "node" {
var.tags,
{
"Name" = local.node_sg_name
"kubernetes.io/cluster/${var.cluster_name}" = "owned"
"kubernetes.io/cluster/${var.name}" = "owned"
},
var.node_security_group_tags
)
@@ -229,26 +191,24 @@ resource "aws_security_group" "node" {
resource "aws_security_group_rule" "node" {
for_each = { for k, v in merge(
local.efa_security_group_rules,
local.node_security_group_rules,
local.node_security_group_recommended_rules,
var.node_security_group_additional_rules,
) : k => v if local.create_node_sg }
# Required
region = var.region
security_group_id = aws_security_group.node[0].id
protocol = each.value.protocol
from_port = each.value.from_port
to_port = each.value.to_port
type = each.value.type
# Optional
description = lookup(each.value, "description", null)
cidr_blocks = lookup(each.value, "cidr_blocks", null)
ipv6_cidr_blocks = lookup(each.value, "ipv6_cidr_blocks", null)
prefix_list_ids = lookup(each.value, "prefix_list_ids", [])
self = lookup(each.value, "self", null)
source_security_group_id = try(each.value.source_cluster_security_group, false) ? local.cluster_security_group_id : lookup(each.value, "source_security_group_id", null)
description = try(each.value.description, null)
cidr_blocks = try(each.value.cidr_blocks, null)
ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null)
prefix_list_ids = try(each.value.prefix_list_ids, null)
self = try(each.value.self, null)
source_security_group_id = try(each.value.source_cluster_security_group, false) ? local.security_group_id : try(each.value.source_security_group_id, null)
}
################################################################################
@@ -258,35 +218,42 @@ resource "aws_security_group_rule" "node" {
module "fargate_profile" {
source = "./modules/fargate-profile"
for_each = { for k, v in var.fargate_profiles : k => v if var.create && !local.create_outposts_local_cluster }
for_each = var.create && !local.create_outposts_local_cluster && var.fargate_profiles != null ? var.fargate_profiles : {}
create = try(each.value.create, true)
create = each.value.create
region = var.region
# Pass through values to reduce GET requests from data sources
partition = local.partition
account_id = local.account_id
# Fargate Profile
cluster_name = time_sleep.this[0].triggers["cluster_name"]
cluster_ip_family = var.cluster_ip_family
name = try(each.value.name, each.key)
subnet_ids = try(each.value.subnet_ids, var.fargate_profile_defaults.subnet_ids, var.subnet_ids)
selectors = try(each.value.selectors, var.fargate_profile_defaults.selectors, [])
timeouts = try(each.value.timeouts, var.fargate_profile_defaults.timeouts, {})
cluster_name = time_sleep.this[0].triggers["name"]
cluster_ip_family = var.ip_family
name = coalesce(each.value.name, each.key)
subnet_ids = coalesce(each.value.subnet_ids, var.subnet_ids)
selectors = each.value.selectors
timeouts = each.value.timeouts
# IAM role
create_iam_role = try(each.value.create_iam_role, var.fargate_profile_defaults.create_iam_role, true)
iam_role_arn = try(each.value.iam_role_arn, var.fargate_profile_defaults.iam_role_arn, null)
iam_role_name = try(each.value.iam_role_name, var.fargate_profile_defaults.iam_role_name, null)
iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.fargate_profile_defaults.iam_role_use_name_prefix, true)
iam_role_path = try(each.value.iam_role_path, var.fargate_profile_defaults.iam_role_path, null)
iam_role_description = try(each.value.iam_role_description, var.fargate_profile_defaults.iam_role_description, "Fargate profile IAM role")
iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.fargate_profile_defaults.iam_role_permissions_boundary, null)
iam_role_tags = try(each.value.iam_role_tags, var.fargate_profile_defaults.iam_role_tags, {})
iam_role_attach_cni_policy = try(each.value.iam_role_attach_cni_policy, var.fargate_profile_defaults.iam_role_attach_cni_policy, true)
# To better understand why this `lookup()` logic is required, see:
# https://github.com/hashicorp/terraform/issues/31646#issuecomment-1217279031
iam_role_additional_policies = lookup(each.value, "iam_role_additional_policies", lookup(var.fargate_profile_defaults, "iam_role_additional_policies", {}))
create_iam_role_policy = try(each.value.create_iam_role_policy, var.fargate_profile_defaults.create_iam_role_policy, true)
iam_role_policy_statements = try(each.value.iam_role_policy_statements, var.fargate_profile_defaults.iam_role_policy_statements, [])
create_iam_role = each.value.create_iam_role
iam_role_arn = each.value.iam_role_arn
iam_role_name = each.value.iam_role_name
iam_role_use_name_prefix = each.value.iam_role_use_name_prefix
iam_role_path = each.value.iam_role_path
iam_role_description = each.value.iam_role_description
iam_role_permissions_boundary = each.value.iam_role_permissions_boundary
iam_role_tags = each.value.iam_role_tags
iam_role_attach_cni_policy = each.value.iam_role_attach_cni_policy
iam_role_additional_policies = lookup(each.value, "iam_role_additional_policies", null)
create_iam_role_policy = each.value.create_iam_role_policy
iam_role_policy_statements = each.value.iam_role_policy_statements
tags = merge(var.tags, try(each.value.tags, var.fargate_profile_defaults.tags, {}))
tags = merge(
var.tags,
each.value.tags,
)
}
################################################################################
@@ -296,120 +263,124 @@ module "fargate_profile" {
module "eks_managed_node_group" {
source = "./modules/eks-managed-node-group"
for_each = { for k, v in var.eks_managed_node_groups : k => v if var.create && !local.create_outposts_local_cluster }
for_each = var.create && !local.create_outposts_local_cluster && var.eks_managed_node_groups != null ? var.eks_managed_node_groups : {}
create = try(each.value.create, true)
create = each.value.create
cluster_name = time_sleep.this[0].triggers["cluster_name"]
cluster_version = try(each.value.cluster_version, var.eks_managed_node_group_defaults.cluster_version, time_sleep.this[0].triggers["cluster_version"])
region = var.region
# Pass through values to reduce GET requests from data sources
partition = local.partition
account_id = local.account_id
cluster_name = time_sleep.this[0].triggers["name"]
kubernetes_version = try(each.value.kubernetes_version, time_sleep.this[0].triggers["kubernetes_version"])
# EKS Managed Node Group
name = try(each.value.name, each.key)
use_name_prefix = try(each.value.use_name_prefix, var.eks_managed_node_group_defaults.use_name_prefix, true)
name = coalesce(each.value.name, each.key)
use_name_prefix = each.value.use_name_prefix
subnet_ids = try(each.value.subnet_ids, var.eks_managed_node_group_defaults.subnet_ids, var.subnet_ids)
subnet_ids = coalesce(each.value.subnet_ids, var.subnet_ids)
min_size = try(each.value.min_size, var.eks_managed_node_group_defaults.min_size, 1)
max_size = try(each.value.max_size, var.eks_managed_node_group_defaults.max_size, 3)
desired_size = try(each.value.desired_size, var.eks_managed_node_group_defaults.desired_size, 1)
min_size = each.value.min_size
max_size = each.value.max_size
desired_size = each.value.desired_size
ami_id = try(each.value.ami_id, var.eks_managed_node_group_defaults.ami_id, "")
ami_type = try(each.value.ami_type, var.eks_managed_node_group_defaults.ami_type, null)
ami_release_version = try(each.value.ami_release_version, var.eks_managed_node_group_defaults.ami_release_version, null)
use_latest_ami_release_version = try(each.value.use_latest_ami_release_version, var.eks_managed_node_group_defaults.use_latest_ami_release_version, false)
ami_id = each.value.ami_id
ami_type = each.value.ami_type
ami_release_version = each.value.ami_release_version
use_latest_ami_release_version = each.value.use_latest_ami_release_version
capacity_type = try(each.value.capacity_type, var.eks_managed_node_group_defaults.capacity_type, null)
disk_size = try(each.value.disk_size, var.eks_managed_node_group_defaults.disk_size, null)
force_update_version = try(each.value.force_update_version, var.eks_managed_node_group_defaults.force_update_version, null)
instance_types = try(each.value.instance_types, var.eks_managed_node_group_defaults.instance_types, null)
labels = try(each.value.labels, var.eks_managed_node_group_defaults.labels, null)
node_repair_config = try(each.value.node_repair_config, var.eks_managed_node_group_defaults.node_repair_config, null)
remote_access = try(each.value.remote_access, var.eks_managed_node_group_defaults.remote_access, {})
taints = try(each.value.taints, var.eks_managed_node_group_defaults.taints, {})
update_config = try(each.value.update_config, var.eks_managed_node_group_defaults.update_config, local.default_update_config)
timeouts = try(each.value.timeouts, var.eks_managed_node_group_defaults.timeouts, {})
capacity_type = each.value.capacity_type
disk_size = each.value.disk_size
force_update_version = each.value.force_update_version
instance_types = each.value.instance_types
labels = each.value.labels
node_repair_config = each.value.node_repair_config
remote_access = each.value.remote_access
taints = each.value.taints
update_config = each.value.update_config
timeouts = each.value.timeouts
# User data
platform = try(each.value.platform, var.eks_managed_node_group_defaults.platform, "linux")
cluster_endpoint = try(time_sleep.this[0].triggers["cluster_endpoint"], "")
cluster_auth_base64 = try(time_sleep.this[0].triggers["cluster_certificate_authority_data"], "")
cluster_service_ipv4_cidr = var.cluster_service_ipv4_cidr
cluster_ip_family = var.cluster_ip_family
cluster_service_cidr = try(time_sleep.this[0].triggers["cluster_service_cidr"], "")
enable_bootstrap_user_data = try(each.value.enable_bootstrap_user_data, var.eks_managed_node_group_defaults.enable_bootstrap_user_data, false)
pre_bootstrap_user_data = try(each.value.pre_bootstrap_user_data, var.eks_managed_node_group_defaults.pre_bootstrap_user_data, "")
post_bootstrap_user_data = try(each.value.post_bootstrap_user_data, var.eks_managed_node_group_defaults.post_bootstrap_user_data, "")
bootstrap_extra_args = try(each.value.bootstrap_extra_args, var.eks_managed_node_group_defaults.bootstrap_extra_args, "")
user_data_template_path = try(each.value.user_data_template_path, var.eks_managed_node_group_defaults.user_data_template_path, "")
cloudinit_pre_nodeadm = try(each.value.cloudinit_pre_nodeadm, var.eks_managed_node_group_defaults.cloudinit_pre_nodeadm, [])
cloudinit_post_nodeadm = try(each.value.cloudinit_post_nodeadm, var.eks_managed_node_group_defaults.cloudinit_post_nodeadm, [])
cluster_endpoint = try(time_sleep.this[0].triggers["endpoint"], "")
cluster_auth_base64 = try(time_sleep.this[0].triggers["certificate_authority_data"], "")
cluster_ip_family = var.ip_family
cluster_service_cidr = try(time_sleep.this[0].triggers["service_cidr"], "")
enable_bootstrap_user_data = each.value.enable_bootstrap_user_data
pre_bootstrap_user_data = each.value.pre_bootstrap_user_data
post_bootstrap_user_data = each.value.post_bootstrap_user_data
bootstrap_extra_args = each.value.bootstrap_extra_args
user_data_template_path = each.value.user_data_template_path
cloudinit_pre_nodeadm = each.value.cloudinit_pre_nodeadm
cloudinit_post_nodeadm = each.value.cloudinit_post_nodeadm
# Launch Template
create_launch_template = try(each.value.create_launch_template, var.eks_managed_node_group_defaults.create_launch_template, true)
use_custom_launch_template = try(each.value.use_custom_launch_template, var.eks_managed_node_group_defaults.use_custom_launch_template, true)
launch_template_id = try(each.value.launch_template_id, var.eks_managed_node_group_defaults.launch_template_id, "")
launch_template_name = try(each.value.launch_template_name, var.eks_managed_node_group_defaults.launch_template_name, each.key)
launch_template_use_name_prefix = try(each.value.launch_template_use_name_prefix, var.eks_managed_node_group_defaults.launch_template_use_name_prefix, true)
launch_template_version = try(each.value.launch_template_version, var.eks_managed_node_group_defaults.launch_template_version, null)
launch_template_default_version = try(each.value.launch_template_default_version, var.eks_managed_node_group_defaults.launch_template_default_version, null)
update_launch_template_default_version = try(each.value.update_launch_template_default_version, var.eks_managed_node_group_defaults.update_launch_template_default_version, true)
launch_template_description = try(each.value.launch_template_description, var.eks_managed_node_group_defaults.launch_template_description, "Custom launch template for ${try(each.value.name, each.key)} EKS managed node group")
launch_template_tags = try(each.value.launch_template_tags, var.eks_managed_node_group_defaults.launch_template_tags, {})
tag_specifications = try(each.value.tag_specifications, var.eks_managed_node_group_defaults.tag_specifications, ["instance", "volume", "network-interface"])
create_launch_template = each.value.create_launch_template
use_custom_launch_template = each.value.use_custom_launch_template
launch_template_id = each.value.launch_template_id
launch_template_name = coalesce(each.value.launch_template_name, each.key)
launch_template_use_name_prefix = each.value.launch_template_use_name_prefix
launch_template_version = each.value.launch_template_version
launch_template_default_version = each.value.launch_template_default_version
update_launch_template_default_version = each.value.update_launch_template_default_version
launch_template_description = coalesce(each.value.launch_template_description, "Custom launch template for ${coalesce(each.value.name, each.key)} EKS managed node group")
launch_template_tags = each.value.launch_template_tags
tag_specifications = each.value.tag_specifications
ebs_optimized = try(each.value.ebs_optimized, var.eks_managed_node_group_defaults.ebs_optimized, null)
key_name = try(each.value.key_name, var.eks_managed_node_group_defaults.key_name, null)
disable_api_termination = try(each.value.disable_api_termination, var.eks_managed_node_group_defaults.disable_api_termination, null)
kernel_id = try(each.value.kernel_id, var.eks_managed_node_group_defaults.kernel_id, null)
ram_disk_id = try(each.value.ram_disk_id, var.eks_managed_node_group_defaults.ram_disk_id, null)
ebs_optimized = each.value.ebs_optimized
key_name = each.value.key_name
disable_api_termination = each.value.disable_api_termination
kernel_id = each.value.kernel_id
ram_disk_id = each.value.ram_disk_id
block_device_mappings = try(each.value.block_device_mappings, var.eks_managed_node_group_defaults.block_device_mappings, {})
capacity_reservation_specification = try(each.value.capacity_reservation_specification, var.eks_managed_node_group_defaults.capacity_reservation_specification, {})
cpu_options = try(each.value.cpu_options, var.eks_managed_node_group_defaults.cpu_options, {})
credit_specification = try(each.value.credit_specification, var.eks_managed_node_group_defaults.credit_specification, {})
elastic_gpu_specifications = try(each.value.elastic_gpu_specifications, var.eks_managed_node_group_defaults.elastic_gpu_specifications, {})
elastic_inference_accelerator = try(each.value.elastic_inference_accelerator, var.eks_managed_node_group_defaults.elastic_inference_accelerator, {})
enclave_options = try(each.value.enclave_options, var.eks_managed_node_group_defaults.enclave_options, {})
instance_market_options = try(each.value.instance_market_options, var.eks_managed_node_group_defaults.instance_market_options, {})
license_specifications = try(each.value.license_specifications, var.eks_managed_node_group_defaults.license_specifications, {})
metadata_options = try(each.value.metadata_options, var.eks_managed_node_group_defaults.metadata_options, local.metadata_options)
enable_monitoring = try(each.value.enable_monitoring, var.eks_managed_node_group_defaults.enable_monitoring, true)
enable_efa_support = try(each.value.enable_efa_support, var.eks_managed_node_group_defaults.enable_efa_support, false)
enable_efa_only = try(each.value.enable_efa_only, var.eks_managed_node_group_defaults.enable_efa_only, false)
efa_indices = try(each.value.efa_indices, var.eks_managed_node_group_defaults.efa_indices, [0])
create_placement_group = try(each.value.create_placement_group, var.eks_managed_node_group_defaults.create_placement_group, false)
placement = try(each.value.placement, var.eks_managed_node_group_defaults.placement, {})
placement_group_az = try(each.value.placement_group_az, var.eks_managed_node_group_defaults.placement_group_az, null)
placement_group_strategy = try(each.value.placement_group_strategy, var.eks_managed_node_group_defaults.placement_group_strategy, "cluster")
network_interfaces = try(each.value.network_interfaces, var.eks_managed_node_group_defaults.network_interfaces, [])
maintenance_options = try(each.value.maintenance_options, var.eks_managed_node_group_defaults.maintenance_options, {})
private_dns_name_options = try(each.value.private_dns_name_options, var.eks_managed_node_group_defaults.private_dns_name_options, {})
block_device_mappings = each.value.block_device_mappings
capacity_reservation_specification = each.value.capacity_reservation_specification
cpu_options = each.value.cpu_options
credit_specification = each.value.credit_specification
enclave_options = each.value.enclave_options
instance_market_options = each.value.instance_market_options
license_specifications = each.value.license_specifications
metadata_options = each.value.metadata_options
enable_monitoring = each.value.enable_monitoring
enable_efa_support = each.value.enable_efa_support
enable_efa_only = each.value.enable_efa_only
efa_indices = each.value.efa_indices
create_placement_group = each.value.create_placement_group
placement = each.value.placement
network_interfaces = each.value.network_interfaces
maintenance_options = each.value.maintenance_options
private_dns_name_options = each.value.private_dns_name_options
# IAM role
create_iam_role = try(each.value.create_iam_role, var.eks_managed_node_group_defaults.create_iam_role, true)
iam_role_arn = try(each.value.iam_role_arn, var.eks_managed_node_group_defaults.iam_role_arn, null)
iam_role_name = try(each.value.iam_role_name, var.eks_managed_node_group_defaults.iam_role_name, null)
iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.eks_managed_node_group_defaults.iam_role_use_name_prefix, true)
iam_role_path = try(each.value.iam_role_path, var.eks_managed_node_group_defaults.iam_role_path, null)
iam_role_description = try(each.value.iam_role_description, var.eks_managed_node_group_defaults.iam_role_description, "EKS managed node group IAM role")
iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.eks_managed_node_group_defaults.iam_role_permissions_boundary, null)
iam_role_tags = try(each.value.iam_role_tags, var.eks_managed_node_group_defaults.iam_role_tags, {})
iam_role_attach_cni_policy = try(each.value.iam_role_attach_cni_policy, var.eks_managed_node_group_defaults.iam_role_attach_cni_policy, true)
# To better understand why this `lookup()` logic is required, see:
# https://github.com/hashicorp/terraform/issues/31646#issuecomment-1217279031
iam_role_additional_policies = lookup(each.value, "iam_role_additional_policies", lookup(var.eks_managed_node_group_defaults, "iam_role_additional_policies", {}))
create_iam_role_policy = try(each.value.create_iam_role_policy, var.eks_managed_node_group_defaults.create_iam_role_policy, true)
iam_role_policy_statements = try(each.value.iam_role_policy_statements, var.eks_managed_node_group_defaults.iam_role_policy_statements, [])
# Autoscaling group schedule
create_schedule = try(each.value.create_schedule, var.eks_managed_node_group_defaults.create_schedule, true)
schedules = try(each.value.schedules, var.eks_managed_node_group_defaults.schedules, {})
create_iam_role = each.value.create_iam_role
iam_role_arn = each.value.iam_role_arn
iam_role_name = each.value.iam_role_name
iam_role_use_name_prefix = each.value.iam_role_use_name_prefix
iam_role_path = each.value.iam_role_path
iam_role_description = each.value.iam_role_description
iam_role_permissions_boundary = each.value.iam_role_permissions_boundary
iam_role_tags = each.value.iam_role_tags
iam_role_attach_cni_policy = each.value.iam_role_attach_cni_policy
iam_role_additional_policies = lookup(each.value, "iam_role_additional_policies", null)
create_iam_role_policy = each.value.create_iam_role_policy
iam_role_policy_statements = each.value.iam_role_policy_statements
# Security group
vpc_security_group_ids = compact(concat([local.node_security_group_id], try(each.value.vpc_security_group_ids, var.eks_managed_node_group_defaults.vpc_security_group_ids, [])))
cluster_primary_security_group_id = try(each.value.attach_cluster_primary_security_group, var.eks_managed_node_group_defaults.attach_cluster_primary_security_group, false) ? aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id : null
vpc_security_group_ids = compact(concat([local.node_security_group_id], each.value.vpc_security_group_ids))
cluster_primary_security_group_id = each.value.attach_cluster_primary_security_group ? aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id : null
create_security_group = each.value.create_security_group
security_group_name = each.value.security_group_name
security_group_use_name_prefix = each.value.security_group_use_name_prefix
security_group_description = each.value.security_group_description
security_group_ingress_rules = each.value.security_group_ingress_rules
security_group_egress_rules = each.value.security_group_egress_rules
security_group_tags = each.value.security_group_tags
tags = merge(var.tags, try(each.value.tags, var.eks_managed_node_group_defaults.tags, {}))
tags = merge(
var.tags,
each.value.tags,
)
}
################################################################################
@@ -419,150 +390,146 @@ module "eks_managed_node_group" {
module "self_managed_node_group" {
source = "./modules/self-managed-node-group"
for_each = { for k, v in var.self_managed_node_groups : k => v if var.create }
for_each = var.create && var.self_managed_node_groups != null ? var.self_managed_node_groups : {}
create = try(each.value.create, true)
create = each.value.create
cluster_name = time_sleep.this[0].triggers["cluster_name"]
region = var.region
# Pass through values to reduce GET requests from data sources
partition = local.partition
account_id = local.account_id
cluster_name = time_sleep.this[0].triggers["name"]
# Autoscaling Group
create_autoscaling_group = try(each.value.create_autoscaling_group, var.self_managed_node_group_defaults.create_autoscaling_group, true)
create_autoscaling_group = each.value.create_autoscaling_group
name = try(each.value.name, each.key)
use_name_prefix = try(each.value.use_name_prefix, var.self_managed_node_group_defaults.use_name_prefix, true)
name = coalesce(each.value.name, each.key)
use_name_prefix = each.value.use_name_prefix
availability_zones = try(each.value.availability_zones, var.self_managed_node_group_defaults.availability_zones, null)
subnet_ids = try(each.value.subnet_ids, var.self_managed_node_group_defaults.subnet_ids, var.subnet_ids)
availability_zones = each.value.availability_zones
subnet_ids = coalesce(each.value.subnet_ids, var.subnet_ids)
min_size = try(each.value.min_size, var.self_managed_node_group_defaults.min_size, 0)
max_size = try(each.value.max_size, var.self_managed_node_group_defaults.max_size, 3)
desired_size = try(each.value.desired_size, var.self_managed_node_group_defaults.desired_size, 1)
desired_size_type = try(each.value.desired_size_type, var.self_managed_node_group_defaults.desired_size_type, null)
capacity_rebalance = try(each.value.capacity_rebalance, var.self_managed_node_group_defaults.capacity_rebalance, null)
min_elb_capacity = try(each.value.min_elb_capacity, var.self_managed_node_group_defaults.min_elb_capacity, null)
wait_for_elb_capacity = try(each.value.wait_for_elb_capacity, var.self_managed_node_group_defaults.wait_for_elb_capacity, null)
wait_for_capacity_timeout = try(each.value.wait_for_capacity_timeout, var.self_managed_node_group_defaults.wait_for_capacity_timeout, null)
default_cooldown = try(each.value.default_cooldown, var.self_managed_node_group_defaults.default_cooldown, null)
default_instance_warmup = try(each.value.default_instance_warmup, var.self_managed_node_group_defaults.default_instance_warmup, null)
protect_from_scale_in = try(each.value.protect_from_scale_in, var.self_managed_node_group_defaults.protect_from_scale_in, null)
context = try(each.value.context, var.self_managed_node_group_defaults.context, null)
min_size = each.value.min_size
max_size = each.value.max_size
desired_size = each.value.desired_size
desired_size_type = each.value.desired_size_type
capacity_rebalance = each.value.capacity_rebalance
default_instance_warmup = each.value.default_instance_warmup
protect_from_scale_in = each.value.protect_from_scale_in
context = each.value.context
target_group_arns = try(each.value.target_group_arns, var.self_managed_node_group_defaults.target_group_arns, [])
create_placement_group = try(each.value.create_placement_group, var.self_managed_node_group_defaults.create_placement_group, false)
placement_group = try(each.value.placement_group, var.self_managed_node_group_defaults.placement_group, null)
placement_group_az = try(each.value.placement_group_az, var.self_managed_node_group_defaults.placement_group_az, null)
health_check_type = try(each.value.health_check_type, var.self_managed_node_group_defaults.health_check_type, null)
health_check_grace_period = try(each.value.health_check_grace_period, var.self_managed_node_group_defaults.health_check_grace_period, null)
create_placement_group = each.value.create_placement_group
placement_group = each.value.placement_group
health_check_type = each.value.health_check_type
health_check_grace_period = each.value.health_check_grace_period
ignore_failed_scaling_activities = try(each.value.ignore_failed_scaling_activities, var.self_managed_node_group_defaults.ignore_failed_scaling_activities, null)
ignore_failed_scaling_activities = each.value.ignore_failed_scaling_activities
force_delete = try(each.value.force_delete, var.self_managed_node_group_defaults.force_delete, null)
force_delete_warm_pool = try(each.value.force_delete_warm_pool, var.self_managed_node_group_defaults.force_delete_warm_pool, null)
termination_policies = try(each.value.termination_policies, var.self_managed_node_group_defaults.termination_policies, [])
suspended_processes = try(each.value.suspended_processes, var.self_managed_node_group_defaults.suspended_processes, [])
max_instance_lifetime = try(each.value.max_instance_lifetime, var.self_managed_node_group_defaults.max_instance_lifetime, null)
force_delete = each.value.force_delete
termination_policies = each.value.termination_policies
suspended_processes = each.value.suspended_processes
max_instance_lifetime = each.value.max_instance_lifetime
enabled_metrics = try(each.value.enabled_metrics, var.self_managed_node_group_defaults.enabled_metrics, [])
metrics_granularity = try(each.value.metrics_granularity, var.self_managed_node_group_defaults.metrics_granularity, null)
service_linked_role_arn = try(each.value.service_linked_role_arn, var.self_managed_node_group_defaults.service_linked_role_arn, null)
enabled_metrics = each.value.enabled_metrics
metrics_granularity = each.value.metrics_granularity
initial_lifecycle_hooks = try(each.value.initial_lifecycle_hooks, var.self_managed_node_group_defaults.initial_lifecycle_hooks, [])
instance_maintenance_policy = try(each.value.instance_maintenance_policy, var.self_managed_node_group_defaults.instance_maintenance_policy, {})
instance_refresh = try(each.value.instance_refresh, var.self_managed_node_group_defaults.instance_refresh, local.default_instance_refresh)
use_mixed_instances_policy = try(each.value.use_mixed_instances_policy, var.self_managed_node_group_defaults.use_mixed_instances_policy, false)
mixed_instances_policy = try(each.value.mixed_instances_policy, var.self_managed_node_group_defaults.mixed_instances_policy, null)
warm_pool = try(each.value.warm_pool, var.self_managed_node_group_defaults.warm_pool, {})
initial_lifecycle_hooks = each.value.initial_lifecycle_hooks
instance_maintenance_policy = each.value.instance_maintenance_policy
instance_refresh = each.value.instance_refresh
use_mixed_instances_policy = each.value.use_mixed_instances_policy
mixed_instances_policy = each.value.mixed_instances_policy
delete_timeout = try(each.value.delete_timeout, var.self_managed_node_group_defaults.delete_timeout, null)
autoscaling_group_tags = try(each.value.autoscaling_group_tags, var.self_managed_node_group_defaults.autoscaling_group_tags, {})
timeouts = each.value.timeouts
autoscaling_group_tags = each.value.autoscaling_group_tags
# User data
platform = try(each.value.platform, var.self_managed_node_group_defaults.platform, null)
# TODO - update this when `var.platform` is removed in v21.0
ami_type = try(each.value.ami_type, var.self_managed_node_group_defaults.ami_type, "AL2_x86_64")
cluster_endpoint = try(time_sleep.this[0].triggers["cluster_endpoint"], "")
cluster_auth_base64 = try(time_sleep.this[0].triggers["cluster_certificate_authority_data"], "")
cluster_service_cidr = try(time_sleep.this[0].triggers["cluster_service_cidr"], "")
additional_cluster_dns_ips = try(each.value.additional_cluster_dns_ips, var.self_managed_node_group_defaults.additional_cluster_dns_ips, [])
cluster_ip_family = var.cluster_ip_family
pre_bootstrap_user_data = try(each.value.pre_bootstrap_user_data, var.self_managed_node_group_defaults.pre_bootstrap_user_data, "")
post_bootstrap_user_data = try(each.value.post_bootstrap_user_data, var.self_managed_node_group_defaults.post_bootstrap_user_data, "")
bootstrap_extra_args = try(each.value.bootstrap_extra_args, var.self_managed_node_group_defaults.bootstrap_extra_args, "")
user_data_template_path = try(each.value.user_data_template_path, var.self_managed_node_group_defaults.user_data_template_path, "")
cloudinit_pre_nodeadm = try(each.value.cloudinit_pre_nodeadm, var.self_managed_node_group_defaults.cloudinit_pre_nodeadm, [])
cloudinit_post_nodeadm = try(each.value.cloudinit_post_nodeadm, var.self_managed_node_group_defaults.cloudinit_post_nodeadm, [])
ami_type = try(each.value.ami_type, null)
cluster_endpoint = try(time_sleep.this[0].triggers["endpoint"], "")
cluster_auth_base64 = try(time_sleep.this[0].triggers["certificate_authority_data"], "")
cluster_service_cidr = try(time_sleep.this[0].triggers["service_cidr"], "")
additional_cluster_dns_ips = try(each.value.additional_cluster_dns_ips, null)
cluster_ip_family = var.ip_family
pre_bootstrap_user_data = try(each.value.pre_bootstrap_user_data, null)
post_bootstrap_user_data = try(each.value.post_bootstrap_user_data, null)
bootstrap_extra_args = try(each.value.bootstrap_extra_args, null)
user_data_template_path = try(each.value.user_data_template_path, null)
cloudinit_pre_nodeadm = try(each.value.cloudinit_pre_nodeadm, null)
cloudinit_post_nodeadm = try(each.value.cloudinit_post_nodeadm, null)
# Launch Template
create_launch_template = try(each.value.create_launch_template, var.self_managed_node_group_defaults.create_launch_template, true)
launch_template_id = try(each.value.launch_template_id, var.self_managed_node_group_defaults.launch_template_id, "")
launch_template_name = try(each.value.launch_template_name, var.self_managed_node_group_defaults.launch_template_name, each.key)
launch_template_use_name_prefix = try(each.value.launch_template_use_name_prefix, var.self_managed_node_group_defaults.launch_template_use_name_prefix, true)
launch_template_version = try(each.value.launch_template_version, var.self_managed_node_group_defaults.launch_template_version, null)
launch_template_default_version = try(each.value.launch_template_default_version, var.self_managed_node_group_defaults.launch_template_default_version, null)
update_launch_template_default_version = try(each.value.update_launch_template_default_version, var.self_managed_node_group_defaults.update_launch_template_default_version, true)
launch_template_description = try(each.value.launch_template_description, var.self_managed_node_group_defaults.launch_template_description, "Custom launch template for ${try(each.value.name, each.key)} self managed node group")
launch_template_tags = try(each.value.launch_template_tags, var.self_managed_node_group_defaults.launch_template_tags, {})
tag_specifications = try(each.value.tag_specifications, var.self_managed_node_group_defaults.tag_specifications, ["instance", "volume", "network-interface"])
create_launch_template = try(each.value.create_launch_template, null)
launch_template_id = try(each.value.launch_template_id, null)
launch_template_name = coalesce(each.value.launch_template_name, each.key)
launch_template_use_name_prefix = try(each.value.launch_template_use_name_prefix, null)
launch_template_version = try(each.value.launch_template_version, null)
launch_template_default_version = try(each.value.launch_template_default_version, null)
update_launch_template_default_version = try(each.value.update_launch_template_default_version, null)
launch_template_description = coalesce(each.value.launch_template_description, "Custom launch template for ${coalesce(each.value.name, each.key)} self managed node group")
launch_template_tags = try(each.value.launch_template_tags, null)
tag_specifications = try(each.value.tag_specifications, null)
ebs_optimized = try(each.value.ebs_optimized, var.self_managed_node_group_defaults.ebs_optimized, null)
ami_id = try(each.value.ami_id, var.self_managed_node_group_defaults.ami_id, "")
cluster_version = try(each.value.cluster_version, var.self_managed_node_group_defaults.cluster_version, time_sleep.this[0].triggers["cluster_version"])
instance_type = try(each.value.instance_type, var.self_managed_node_group_defaults.instance_type, "m6i.large")
key_name = try(each.value.key_name, var.self_managed_node_group_defaults.key_name, null)
ebs_optimized = try(each.value.ebs_optimized, null)
ami_id = try(each.value.ami_id, null)
kubernetes_version = try(each.value.kubernetes_version, time_sleep.this[0].triggers["kubernetes_version"])
instance_type = try(each.value.instance_type, null)
key_name = try(each.value.key_name, null)
disable_api_termination = try(each.value.disable_api_termination, var.self_managed_node_group_defaults.disable_api_termination, null)
instance_initiated_shutdown_behavior = try(each.value.instance_initiated_shutdown_behavior, var.self_managed_node_group_defaults.instance_initiated_shutdown_behavior, null)
kernel_id = try(each.value.kernel_id, var.self_managed_node_group_defaults.kernel_id, null)
ram_disk_id = try(each.value.ram_disk_id, var.self_managed_node_group_defaults.ram_disk_id, null)
disable_api_termination = try(each.value.disable_api_termination, null)
instance_initiated_shutdown_behavior = try(each.value.instance_initiated_shutdown_behavior, null)
kernel_id = try(each.value.kernel_id, null)
ram_disk_id = try(each.value.ram_disk_id, null)
block_device_mappings = try(each.value.block_device_mappings, var.self_managed_node_group_defaults.block_device_mappings, {})
capacity_reservation_specification = try(each.value.capacity_reservation_specification, var.self_managed_node_group_defaults.capacity_reservation_specification, {})
cpu_options = try(each.value.cpu_options, var.self_managed_node_group_defaults.cpu_options, {})
credit_specification = try(each.value.credit_specification, var.self_managed_node_group_defaults.credit_specification, {})
elastic_gpu_specifications = try(each.value.elastic_gpu_specifications, var.self_managed_node_group_defaults.elastic_gpu_specifications, {})
elastic_inference_accelerator = try(each.value.elastic_inference_accelerator, var.self_managed_node_group_defaults.elastic_inference_accelerator, {})
enclave_options = try(each.value.enclave_options, var.self_managed_node_group_defaults.enclave_options, {})
hibernation_options = try(each.value.hibernation_options, var.self_managed_node_group_defaults.hibernation_options, {})
instance_requirements = try(each.value.instance_requirements, var.self_managed_node_group_defaults.instance_requirements, {})
instance_market_options = try(each.value.instance_market_options, var.self_managed_node_group_defaults.instance_market_options, {})
license_specifications = try(each.value.license_specifications, var.self_managed_node_group_defaults.license_specifications, {})
metadata_options = try(each.value.metadata_options, var.self_managed_node_group_defaults.metadata_options, local.metadata_options)
enable_monitoring = try(each.value.enable_monitoring, var.self_managed_node_group_defaults.enable_monitoring, true)
enable_efa_support = try(each.value.enable_efa_support, var.self_managed_node_group_defaults.enable_efa_support, false)
enable_efa_only = try(each.value.enable_efa_only, var.self_managed_node_group_defaults.enable_efa_only, false)
efa_indices = try(each.value.efa_indices, var.self_managed_node_group_defaults.efa_indices, [0])
network_interfaces = try(each.value.network_interfaces, var.self_managed_node_group_defaults.network_interfaces, [])
placement = try(each.value.placement, var.self_managed_node_group_defaults.placement, {})
maintenance_options = try(each.value.maintenance_options, var.self_managed_node_group_defaults.maintenance_options, {})
private_dns_name_options = try(each.value.private_dns_name_options, var.self_managed_node_group_defaults.private_dns_name_options, {})
block_device_mappings = try(each.value.block_device_mappings, null)
capacity_reservation_specification = try(each.value.capacity_reservation_specification, null)
cpu_options = try(each.value.cpu_options, null)
credit_specification = try(each.value.credit_specification, null)
enclave_options = try(each.value.enclave_options, null)
instance_requirements = try(each.value.instance_requirements, null)
instance_market_options = try(each.value.instance_market_options, null)
license_specifications = try(each.value.license_specifications, null)
metadata_options = try(each.value.metadata_options, null)
enable_monitoring = try(each.value.enable_monitoring, null)
enable_efa_support = try(each.value.enable_efa_support, null)
enable_efa_only = try(each.value.enable_efa_only, null)
efa_indices = try(each.value.efa_indices, null)
network_interfaces = try(each.value.network_interfaces, null)
placement = try(each.value.placement, null)
maintenance_options = try(each.value.maintenance_options, null)
private_dns_name_options = try(each.value.private_dns_name_options, null)
# IAM role
create_iam_instance_profile = try(each.value.create_iam_instance_profile, var.self_managed_node_group_defaults.create_iam_instance_profile, true)
iam_instance_profile_arn = try(each.value.iam_instance_profile_arn, var.self_managed_node_group_defaults.iam_instance_profile_arn, null)
iam_role_name = try(each.value.iam_role_name, var.self_managed_node_group_defaults.iam_role_name, null)
iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.self_managed_node_group_defaults.iam_role_use_name_prefix, true)
iam_role_path = try(each.value.iam_role_path, var.self_managed_node_group_defaults.iam_role_path, null)
iam_role_description = try(each.value.iam_role_description, var.self_managed_node_group_defaults.iam_role_description, "Self managed node group IAM role")
iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.self_managed_node_group_defaults.iam_role_permissions_boundary, null)
iam_role_tags = try(each.value.iam_role_tags, var.self_managed_node_group_defaults.iam_role_tags, {})
iam_role_attach_cni_policy = try(each.value.iam_role_attach_cni_policy, var.self_managed_node_group_defaults.iam_role_attach_cni_policy, true)
# To better understand why this `lookup()` logic is required, see:
# https://github.com/hashicorp/terraform/issues/31646#issuecomment-1217279031
iam_role_additional_policies = lookup(each.value, "iam_role_additional_policies", lookup(var.self_managed_node_group_defaults, "iam_role_additional_policies", {}))
create_iam_role_policy = try(each.value.create_iam_role_policy, var.self_managed_node_group_defaults.create_iam_role_policy, true)
iam_role_policy_statements = try(each.value.iam_role_policy_statements, var.self_managed_node_group_defaults.iam_role_policy_statements, [])
create_iam_instance_profile = try(each.value.create_iam_instance_profile, null)
iam_instance_profile_arn = try(each.value.iam_instance_profile_arn, null)
iam_role_name = try(each.value.iam_role_name, null)
iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, true)
iam_role_path = try(each.value.iam_role_path, null)
iam_role_description = try(each.value.iam_role_description, null)
iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, null)
iam_role_tags = try(each.value.iam_role_tags, null)
iam_role_attach_cni_policy = try(each.value.iam_role_attach_cni_policy, null)
iam_role_additional_policies = lookup(each.value, "iam_role_additional_policies", null)
create_iam_role_policy = try(each.value.create_iam_role_policy, null)
iam_role_policy_statements = try(each.value.iam_role_policy_statements, null)
# Access entry
create_access_entry = try(each.value.create_access_entry, var.self_managed_node_group_defaults.create_access_entry, true)
iam_role_arn = try(each.value.iam_role_arn, var.self_managed_node_group_defaults.iam_role_arn, null)
# Autoscaling group schedule
create_schedule = try(each.value.create_schedule, var.self_managed_node_group_defaults.create_schedule, true)
schedules = try(each.value.schedules, var.self_managed_node_group_defaults.schedules, {})
create_access_entry = try(each.value.create_access_entry, null)
iam_role_arn = try(each.value.iam_role_arn, null)
# Security group
vpc_security_group_ids = compact(concat([local.node_security_group_id], try(each.value.vpc_security_group_ids, var.self_managed_node_group_defaults.vpc_security_group_ids, [])))
cluster_primary_security_group_id = try(each.value.attach_cluster_primary_security_group, var.self_managed_node_group_defaults.attach_cluster_primary_security_group, false) ? aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id : null
vpc_security_group_ids = compact(concat([local.node_security_group_id], try(each.value.vpc_security_group_ids, [])))
cluster_primary_security_group_id = try(each.value.attach_cluster_primary_security_group, false) ? aws_eks_cluster.this[0].vpc_config[0].cluster_security_group_id : null
create_security_group = try(each.value.create_security_group, null)
security_group_name = try(each.value.security_group_name, null)
security_group_use_name_prefix = try(each.value.security_group_use_name_prefix, null)
security_group_description = try(each.value.security_group_description, null)
security_group_ingress_rules = try(each.value.security_group_ingress_rules, null)
security_group_egress_rules = try(each.value.security_group_egress_rules, null)
security_group_tags = try(each.value.security_group_tags, null)
tags = merge(var.tags, try(each.value.tags, var.self_managed_node_group_defaults.tags, {}))
tags = merge(
var.tags,
each.value.tags,
)
}
+2 -1
View File
@@ -1,4 +1,5 @@
locals {
# https://github.com/aws/containers-roadmap/issues/2038#issuecomment-2278450601
dualstack_oidc_issuer_url = try(replace(replace(aws_eks_cluster.this[0].identity[0].oidc[0].issuer, "https://oidc.eks.", "https://oidc-eks."), ".amazonaws.com/", ".api.aws/"), null)
}
@@ -83,7 +84,7 @@ output "cluster_primary_security_group_id" {
output "cluster_service_cidr" {
description = "The CIDR block where Kubernetes pod and service IP addresses are assigned from"
value = var.cluster_ip_family == "ipv6" ? try(aws_eks_cluster.this[0].kubernetes_network_config[0].service_ipv6_cidr, null) : try(aws_eks_cluster.this[0].kubernetes_network_config[0].service_ipv4_cidr, null)
value = var.ip_family == "ipv6" ? try(aws_eks_cluster.this[0].kubernetes_network_config[0].service_ipv6_cidr, null) : try(aws_eks_cluster.this[0].kubernetes_network_config[0].service_ipv4_cidr, null)
}
output "cluster_ip_family" {
+4 -4
View File
@@ -17,14 +17,14 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -33,7 +33,7 @@ Note that this example may create resources which cost money. Run `terraform des
| <a name="module_disabled_fargate_profile"></a> [disabled\_fargate\_profile](#module\_disabled\_fargate\_profile) | ../../modules/fargate-profile | n/a |
| <a name="module_eks"></a> [eks](#module\_eks) | ../.. | n/a |
| <a name="module_fargate_profile"></a> [fargate\_profile](#module\_fargate\_profile) | ../../modules/fargate-profile | n/a |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
+11 -13
View File
@@ -12,7 +12,7 @@ data "aws_availability_zones" "available" {
locals {
name = "ex-${basename(path.cwd)}"
cluster_version = "1.33"
kubernetes_version = "1.33"
region = "eu-west-1"
vpc_cidr = "10.0.0.0/16"
@@ -32,11 +32,11 @@ locals {
module "eks" {
source = "../.."
cluster_name = local.name
cluster_version = local.cluster_version
cluster_endpoint_public_access = true
name = local.name
kubernetes_version = local.kubernetes_version
endpoint_public_access = true
cluster_addons = {
addons = {
kube-proxy = {}
vpc-cni = {}
coredns = {
@@ -51,15 +51,9 @@ module "eks" {
control_plane_subnet_ids = module.vpc.intra_subnets
# Fargate profiles use the cluster primary security group so these are not utilized
create_cluster_security_group = false
create_security_group = false
create_node_security_group = false
fargate_profile_defaults = {
iam_role_additional_policies = {
additional = aws_iam_policy.additional.arn
}
}
fargate_profiles = {
example = {
name = "example"
@@ -78,6 +72,10 @@ module "eks" {
}
]
iam_role_additional_policies = {
additional = aws_iam_policy.additional.arn
}
# Using specific subnets instead of the subnets supplied for the cluster itself
subnet_ids = [module.vpc.private_subnets[1]]
@@ -125,7 +123,7 @@ module "disabled_fargate_profile" {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+2 -2
View File
@@ -17,8 +17,8 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_tls"></a> [tls](#requirement\_tls) | >= 4.0 |
## Providers
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
tls = {
source = "hashicorp/tls"
+5 -5
View File
@@ -17,14 +17,14 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -33,11 +33,11 @@ Note that this example may create resources which cost money. Run `terraform des
| <a name="module_aws_vpc_cni_ipv6_pod_identity"></a> [aws\_vpc\_cni\_ipv6\_pod\_identity](#module\_aws\_vpc\_cni\_ipv6\_pod\_identity) | terraform-aws-modules/eks-pod-identity/aws | ~> 1.6 |
| <a name="module_disabled_eks"></a> [disabled\_eks](#module\_disabled\_eks) | ../.. | n/a |
| <a name="module_disabled_eks_managed_node_group"></a> [disabled\_eks\_managed\_node\_group](#module\_disabled\_eks\_managed\_node\_group) | ../../modules/eks-managed-node-group | n/a |
| <a name="module_ebs_kms_key"></a> [ebs\_kms\_key](#module\_ebs\_kms\_key) | terraform-aws-modules/kms/aws | ~> 2.1 |
| <a name="module_ebs_kms_key"></a> [ebs\_kms\_key](#module\_ebs\_kms\_key) | terraform-aws-modules/kms/aws | ~> 4.0 |
| <a name="module_eks"></a> [eks](#module\_eks) | ../.. | n/a |
| <a name="module_eks_managed_node_group"></a> [eks\_managed\_node\_group](#module\_eks\_managed\_node\_group) | ../../modules/eks-managed-node-group | n/a |
| <a name="module_key_pair"></a> [key\_pair](#module\_key\_pair) | terraform-aws-modules/key-pair/aws | ~> 2.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
+16 -29
View File
@@ -14,7 +14,7 @@ data "aws_availability_zones" "available" {
locals {
name = "ex-${replace(basename(path.cwd), "_", "-")}"
cluster_version = "1.33"
kubernetes_version = "1.33"
region = "eu-west-1"
vpc_cidr = "10.0.0.0/16"
@@ -34,21 +34,17 @@ locals {
module "eks" {
source = "../.."
cluster_name = local.name
cluster_version = local.cluster_version
cluster_endpoint_public_access = true
name = local.name
kubernetes_version = local.kubernetes_version
endpoint_public_access = true
# IPV6
cluster_ip_family = "ipv6"
ip_family = "ipv6"
create_cni_ipv6_iam_policy = true
enable_cluster_creator_admin_permissions = true
# Enable EFA support by adding necessary security group rules
# to the shared node security group
enable_efa_support = true
cluster_addons = {
addons = {
coredns = {
most_recent = true
}
@@ -79,11 +75,11 @@ module "eks" {
}
}
cluster_upgrade_policy = {
upgrade_policy = {
support_type = "STANDARD"
}
cluster_zonal_shift_config = {
zonal_shift_config = {
enabled = true
}
@@ -91,11 +87,6 @@ module "eks" {
subnet_ids = module.vpc.private_subnets
control_plane_subnet_ids = module.vpc.intra_subnets
eks_managed_node_group_defaults = {
ami_type = "AL2023_x86_64_STANDARD"
instance_types = ["m6i.large", "m5.large", "m5n.large", "m5zn.large"]
}
eks_managed_node_groups = {
# Default node group - as provided by AWS EKS
default_node_group = {
@@ -114,8 +105,8 @@ module "eks" {
placement_group = {
create_placement_group = true
# forces the subnet lookup to be restricted to this availability zone
placement_group_az = element(local.azs, 3)
subnet_ids = slice(module.vpc.private_subnets, 0, 1)
instance_types = ["m5.large", "m5n.large", "m5zn.large"]
}
# AL2023 node group utilizing new user data format which utilizes nodeadm
@@ -135,8 +126,6 @@ module "eks" {
kubelet:
config:
shutdownGracePeriod: 30s
featureGates:
DisableKubeletCloudCredentialProviders: true
EOT
}
]
@@ -238,8 +227,6 @@ module "eks" {
kubelet:
config:
shutdownGracePeriod: 30s
featureGates:
DisableKubeletCloudCredentialProviders: true
EOT
content_type = "application/node.eks.aws"
}]
@@ -359,7 +346,7 @@ module "eks" {
# This will:
# 1. Create a placement group to place the instances close to one another
# 2. Ignore subnets that reside in AZs that do not support the instance type
# 2. Create and attach the necessary security group rules (and security group)
# 3. Expose all of the available EFA interfaces on the launch template
enable_efa_support = true
enable_efa_only = true
@@ -476,7 +463,7 @@ module "disabled_eks_managed_node_group" {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
@@ -523,7 +510,7 @@ module "aws_vpc_cni_ipv6_pod_identity" {
module "ebs_kms_key" {
source = "terraform-aws-modules/kms/aws"
version = "~> 2.1"
version = "~> 4.0"
description = "Customer managed key to encrypt EKS managed node group volumes"
@@ -605,7 +592,7 @@ data "aws_ami" "eks_default" {
filter {
name = "name"
values = ["amazon-eks-node-al2023-x86_64-standard-${local.cluster_version}-v*"]
values = ["amazon-eks-node-al2023-x86_64-standard-${local.kubernetes_version}-v*"]
}
}
@@ -615,7 +602,7 @@ data "aws_ami" "eks_default_arm" {
filter {
name = "name"
values = ["amazon-eks-node-al2023-arm64-standard-${local.cluster_version}-v*"]
values = ["amazon-eks-node-al2023-arm64-standard-${local.kubernetes_version}-v*"]
}
}
@@ -625,7 +612,7 @@ data "aws_ami" "eks_default_bottlerocket" {
filter {
name = "name"
values = ["bottlerocket-aws-k8s-${local.cluster_version}-x86_64-*"]
values = ["bottlerocket-aws-k8s-${local.kubernetes_version}-x86_64-*"]
}
}
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
-92
View File
@@ -1,92 +0,0 @@
# Fast Addons
Refer to https://github.com/terraform-aws-modules/terraform-aws-eks/pull/3214 for additional information.
<!-- TODO - remove this at next breaking change since the defaults will be in place -->
## Usage
To provision the provided configurations you need to execute:
```bash
$ terraform init
$ terraform plan
$ terraform apply --auto-approve
```
Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_eks"></a> [eks](#module\_eks) | ../.. | n/a |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
## Resources
| Name | Type |
|------|------|
| [aws_route_table_association.custom_network](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_subnet.custom_network](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_vpc_ipv4_cidr_block_association.custom_network](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipv4_cidr_block_association) | resource |
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
## Inputs
No inputs.
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_access_entries"></a> [access\_entries](#output\_access\_entries) | Map of access entries created and their attributes |
| <a name="output_cloudwatch_log_group_arn"></a> [cloudwatch\_log\_group\_arn](#output\_cloudwatch\_log\_group\_arn) | Arn of cloudwatch log group created |
| <a name="output_cloudwatch_log_group_name"></a> [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of cloudwatch log group created |
| <a name="output_cluster_addons"></a> [cluster\_addons](#output\_cluster\_addons) | Map of attribute maps for all EKS cluster addons enabled |
| <a name="output_cluster_arn"></a> [cluster\_arn](#output\_cluster\_arn) | The Amazon Resource Name (ARN) of the cluster |
| <a name="output_cluster_certificate_authority_data"></a> [cluster\_certificate\_authority\_data](#output\_cluster\_certificate\_authority\_data) | Base64 encoded certificate data required to communicate with the cluster |
| <a name="output_cluster_dualstack_oidc_issuer_url"></a> [cluster\_dualstack\_oidc\_issuer\_url](#output\_cluster\_dualstack\_oidc\_issuer\_url) | Dual-stack compatible URL on the EKS cluster for the OpenID Connect identity provider |
| <a name="output_cluster_endpoint"></a> [cluster\_endpoint](#output\_cluster\_endpoint) | Endpoint for your Kubernetes API server |
| <a name="output_cluster_iam_role_arn"></a> [cluster\_iam\_role\_arn](#output\_cluster\_iam\_role\_arn) | IAM role ARN of the EKS cluster |
| <a name="output_cluster_iam_role_name"></a> [cluster\_iam\_role\_name](#output\_cluster\_iam\_role\_name) | IAM role name of the EKS cluster |
| <a name="output_cluster_iam_role_unique_id"></a> [cluster\_iam\_role\_unique\_id](#output\_cluster\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role |
| <a name="output_cluster_id"></a> [cluster\_id](#output\_cluster\_id) | The ID of the EKS cluster. Note: currently a value is returned only for local EKS clusters created on Outposts |
| <a name="output_cluster_identity_providers"></a> [cluster\_identity\_providers](#output\_cluster\_identity\_providers) | Map of attribute maps for all EKS identity providers enabled |
| <a name="output_cluster_ip_family"></a> [cluster\_ip\_family](#output\_cluster\_ip\_family) | The IP family used by the cluster (e.g. `ipv4` or `ipv6`) |
| <a name="output_cluster_name"></a> [cluster\_name](#output\_cluster\_name) | The name of the EKS cluster |
| <a name="output_cluster_oidc_issuer_url"></a> [cluster\_oidc\_issuer\_url](#output\_cluster\_oidc\_issuer\_url) | The URL on the EKS cluster for the OpenID Connect identity provider |
| <a name="output_cluster_platform_version"></a> [cluster\_platform\_version](#output\_cluster\_platform\_version) | Platform version for the cluster |
| <a name="output_cluster_primary_security_group_id"></a> [cluster\_primary\_security\_group\_id](#output\_cluster\_primary\_security\_group\_id) | Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console |
| <a name="output_cluster_security_group_arn"></a> [cluster\_security\_group\_arn](#output\_cluster\_security\_group\_arn) | Amazon Resource Name (ARN) of the cluster security group |
| <a name="output_cluster_security_group_id"></a> [cluster\_security\_group\_id](#output\_cluster\_security\_group\_id) | ID of the cluster security group |
| <a name="output_cluster_service_cidr"></a> [cluster\_service\_cidr](#output\_cluster\_service\_cidr) | The CIDR block where Kubernetes pod and service IP addresses are assigned from |
| <a name="output_cluster_status"></a> [cluster\_status](#output\_cluster\_status) | Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED` |
| <a name="output_cluster_tls_certificate_sha1_fingerprint"></a> [cluster\_tls\_certificate\_sha1\_fingerprint](#output\_cluster\_tls\_certificate\_sha1\_fingerprint) | The SHA1 fingerprint of the public key of the cluster's certificate |
| <a name="output_eks_managed_node_groups"></a> [eks\_managed\_node\_groups](#output\_eks\_managed\_node\_groups) | Map of attribute maps for all EKS managed node groups created |
| <a name="output_eks_managed_node_groups_autoscaling_group_names"></a> [eks\_managed\_node\_groups\_autoscaling\_group\_names](#output\_eks\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by EKS managed node groups |
| <a name="output_fargate_profiles"></a> [fargate\_profiles](#output\_fargate\_profiles) | Map of attribute maps for all EKS Fargate Profiles created |
| <a name="output_kms_key_arn"></a> [kms\_key\_arn](#output\_kms\_key\_arn) | The Amazon Resource Name (ARN) of the key |
| <a name="output_kms_key_id"></a> [kms\_key\_id](#output\_kms\_key\_id) | The globally unique identifier for the key |
| <a name="output_kms_key_policy"></a> [kms\_key\_policy](#output\_kms\_key\_policy) | The IAM resource policy set on the key |
| <a name="output_node_security_group_arn"></a> [node\_security\_group\_arn](#output\_node\_security\_group\_arn) | Amazon Resource Name (ARN) of the node shared security group |
| <a name="output_node_security_group_id"></a> [node\_security\_group\_id](#output\_node\_security\_group\_id) | ID of the node shared security group |
| <a name="output_oidc_provider"></a> [oidc\_provider](#output\_oidc\_provider) | The OpenID Connect identity provider (issuer URL without leading `https://`) |
| <a name="output_oidc_provider_arn"></a> [oidc\_provider\_arn](#output\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` |
| <a name="output_self_managed_node_groups"></a> [self\_managed\_node\_groups](#output\_self\_managed\_node\_groups) | Map of attribute maps for all self managed node groups created |
| <a name="output_self_managed_node_groups_autoscaling_group_names"></a> [self\_managed\_node\_groups\_autoscaling\_group\_names](#output\_self\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by self-managed node groups |
<!-- END_TF_DOCS -->
-159
View File
@@ -1,159 +0,0 @@
provider "aws" {
region = local.region
}
locals {
name = "ex-${basename(path.cwd)}"
cluster_version = "1.33"
region = "eu-west-1"
tags = {
Test = local.name
GithubRepo = "terraform-aws-eks"
GithubOrg = "terraform-aws-modules"
}
}
################################################################################
# EKS Module
################################################################################
module "eks" {
source = "../.."
cluster_name = local.name
cluster_version = local.cluster_version
cluster_endpoint_public_access = true
enable_cluster_creator_admin_permissions = true
# Disable the default self-managed addons to avoid the penalty of adopting them later
bootstrap_self_managed_addons = false
# Addons will be provisioned net new via the EKS addon API
cluster_addons = {
coredns = {
most_recent = true
}
eks-pod-identity-agent = {
before_compute = true
most_recent = true
}
kube-proxy = {
most_recent = true
}
vpc-cni = {
most_recent = true
before_compute = true
configuration_values = jsonencode({
env = {
# Use subnet tags to avoid the need to inject the ENIConfig
# which requires a live API server endpoint which leads to a dependency of:
# Control plane -> API request to create ENIConfig -> VPC CNI addon -> nodes/compute
# With the subnet discovery feature, we can avoid this dependency:
# Control plane -> VPC CNI addon -> nodes/compute
ENABLE_SUBNET_DISCOVERY = "true"
}
})
}
}
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
eks_managed_node_groups = {
example = {
instance_types = ["m6i.large"]
min_size = 2
max_size = 5
desired_size = 2
}
}
tags = local.tags
}
################################################################################
# VPC
################################################################################
data "aws_availability_zones" "available" {
# Exclude local zones
filter {
name = "opt-in-status"
values = ["opt-in-not-required"]
}
}
locals {
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]
enable_nat_gateway = true
single_nat_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
tags = local.tags
}
################################################################################
# Custom Networking
################################################################################
locals {
custom_network_vpc_cidr = "10.99.0.0/16"
custom_network_subnets = [for k, v in local.azs : cidrsubnet(local.custom_network_vpc_cidr, 4, k)]
}
resource "aws_vpc_ipv4_cidr_block_association" "custom_network" {
vpc_id = module.vpc.vpc_id
cidr_block = local.custom_network_vpc_cidr
}
resource "aws_subnet" "custom_network" {
count = length(local.custom_network_subnets)
vpc_id = module.vpc.vpc_id
cidr_block = element(local.custom_network_subnets, count.index)
tags = merge(
local.tags,
{
# Tag for subnet discovery
"kubernetes.io/role/cni" = 1
"kubernetes.io/role/internal-elb" = 1
}
)
depends_on = [
aws_vpc_ipv4_cidr_block_association.custom_network
]
}
resource "aws_route_table_association" "custom_network" {
count = length(local.custom_network_subnets)
subnet_id = element(aws_subnet.custom_network[*].id, count.index)
route_table_id = element(module.vpc.private_route_table_ids, 0)
depends_on = [
aws_vpc_ipv4_cidr_block_association.custom_network
]
}
-226
View File
@@ -1,226 +0,0 @@
################################################################################
# Cluster
################################################################################
output "cluster_arn" {
description = "The Amazon Resource Name (ARN) of the cluster"
value = module.eks.cluster_arn
}
output "cluster_certificate_authority_data" {
description = "Base64 encoded certificate data required to communicate with the cluster"
value = module.eks.cluster_certificate_authority_data
}
output "cluster_endpoint" {
description = "Endpoint for your Kubernetes API server"
value = module.eks.cluster_endpoint
}
output "cluster_id" {
description = "The ID of the EKS cluster. Note: currently a value is returned only for local EKS clusters created on Outposts"
value = module.eks.cluster_id
}
output "cluster_name" {
description = "The name of the EKS cluster"
value = module.eks.cluster_name
}
output "cluster_oidc_issuer_url" {
description = "The URL on the EKS cluster for the OpenID Connect identity provider"
value = module.eks.cluster_oidc_issuer_url
}
output "cluster_dualstack_oidc_issuer_url" {
description = "Dual-stack compatible URL on the EKS cluster for the OpenID Connect identity provider"
value = module.eks.cluster_dualstack_oidc_issuer_url
}
output "cluster_platform_version" {
description = "Platform version for the cluster"
value = module.eks.cluster_platform_version
}
output "cluster_status" {
description = "Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED`"
value = module.eks.cluster_status
}
output "cluster_primary_security_group_id" {
description = "Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console"
value = module.eks.cluster_primary_security_group_id
}
output "cluster_service_cidr" {
description = "The CIDR block where Kubernetes pod and service IP addresses are assigned from"
value = module.eks.cluster_service_cidr
}
output "cluster_ip_family" {
description = "The IP family used by the cluster (e.g. `ipv4` or `ipv6`)"
value = module.eks.cluster_ip_family
}
################################################################################
# Access Entry
################################################################################
output "access_entries" {
description = "Map of access entries created and their attributes"
value = module.eks.access_entries
}
################################################################################
# KMS Key
################################################################################
output "kms_key_arn" {
description = "The Amazon Resource Name (ARN) of the key"
value = module.eks.kms_key_arn
}
output "kms_key_id" {
description = "The globally unique identifier for the key"
value = module.eks.kms_key_id
}
output "kms_key_policy" {
description = "The IAM resource policy set on the key"
value = module.eks.kms_key_policy
}
################################################################################
# Security Group
################################################################################
output "cluster_security_group_arn" {
description = "Amazon Resource Name (ARN) of the cluster security group"
value = module.eks.cluster_security_group_arn
}
output "cluster_security_group_id" {
description = "ID of the cluster security group"
value = module.eks.cluster_security_group_id
}
################################################################################
# Node Security Group
################################################################################
output "node_security_group_arn" {
description = "Amazon Resource Name (ARN) of the node shared security group"
value = module.eks.node_security_group_arn
}
output "node_security_group_id" {
description = "ID of the node shared security group"
value = module.eks.node_security_group_id
}
################################################################################
# IRSA
################################################################################
output "oidc_provider" {
description = "The OpenID Connect identity provider (issuer URL without leading `https://`)"
value = module.eks.oidc_provider
}
output "oidc_provider_arn" {
description = "The ARN of the OIDC Provider if `enable_irsa = true`"
value = module.eks.oidc_provider_arn
}
output "cluster_tls_certificate_sha1_fingerprint" {
description = "The SHA1 fingerprint of the public key of the cluster's certificate"
value = module.eks.cluster_tls_certificate_sha1_fingerprint
}
################################################################################
# IAM Role
################################################################################
output "cluster_iam_role_name" {
description = "IAM role name of the EKS cluster"
value = module.eks.cluster_iam_role_name
}
output "cluster_iam_role_arn" {
description = "IAM role ARN of the EKS cluster"
value = module.eks.cluster_iam_role_arn
}
output "cluster_iam_role_unique_id" {
description = "Stable and unique string identifying the IAM role"
value = module.eks.cluster_iam_role_unique_id
}
################################################################################
# EKS Addons
################################################################################
output "cluster_addons" {
description = "Map of attribute maps for all EKS cluster addons enabled"
value = module.eks.cluster_addons
}
################################################################################
# EKS Identity Provider
################################################################################
output "cluster_identity_providers" {
description = "Map of attribute maps for all EKS identity providers enabled"
value = module.eks.cluster_identity_providers
}
################################################################################
# CloudWatch Log Group
################################################################################
output "cloudwatch_log_group_name" {
description = "Name of cloudwatch log group created"
value = module.eks.cloudwatch_log_group_name
}
output "cloudwatch_log_group_arn" {
description = "Arn of cloudwatch log group created"
value = module.eks.cloudwatch_log_group_arn
}
################################################################################
# Fargate Profile
################################################################################
output "fargate_profiles" {
description = "Map of attribute maps for all EKS Fargate Profiles created"
value = module.eks.fargate_profiles
}
################################################################################
# EKS Managed Node Group
################################################################################
output "eks_managed_node_groups" {
description = "Map of attribute maps for all EKS managed node groups created"
value = module.eks.eks_managed_node_groups
}
output "eks_managed_node_groups_autoscaling_group_names" {
description = "List of the autoscaling group names created by EKS managed node groups"
value = module.eks.eks_managed_node_groups_autoscaling_group_names
}
################################################################################
# Self Managed Node Group
################################################################################
output "self_managed_node_groups" {
description = "Map of attribute maps for all self managed node groups created"
value = module.eks.self_managed_node_groups
}
output "self_managed_node_groups_autoscaling_group_names" {
description = "List of the autoscaling group names created by self-managed node groups"
value = module.eks.self_managed_node_groups_autoscaling_group_names
}
View File
-10
View File
@@ -1,10 +0,0 @@
terraform {
required_version = ">= 1.3.2"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
}
}
}
+6 -6
View File
@@ -17,14 +17,14 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.95, < 6.0.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.95, < 6.0.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
## Modules
@@ -32,11 +32,11 @@ Note that this example may create resources which cost money. Run `terraform des
|------|--------|---------|
| <a name="module_aws_vpc_cni_ipv4_pod_identity"></a> [aws\_vpc\_cni\_ipv4\_pod\_identity](#module\_aws\_vpc\_cni\_ipv4\_pod\_identity) | terraform-aws-modules/eks-pod-identity/aws | ~> 1.6 |
| <a name="module_disabled_self_managed_node_group"></a> [disabled\_self\_managed\_node\_group](#module\_disabled\_self\_managed\_node\_group) | ../../modules/self-managed-node-group | n/a |
| <a name="module_ebs_kms_key"></a> [ebs\_kms\_key](#module\_ebs\_kms\_key) | terraform-aws-modules/kms/aws | ~> 2.0 |
| <a name="module_ebs_kms_key"></a> [ebs\_kms\_key](#module\_ebs\_kms\_key) | terraform-aws-modules/kms/aws | ~> 4.0 |
| <a name="module_eks"></a> [eks](#module\_eks) | ../.. | n/a |
| <a name="module_key_pair"></a> [key\_pair](#module\_key\_pair) | terraform-aws-modules/key-pair/aws | ~> 2.0 |
| <a name="module_kms"></a> [kms](#module\_kms) | terraform-aws-modules/kms/aws | ~> 2.1 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
| <a name="module_kms"></a> [kms](#module\_kms) | terraform-aws-modules/kms/aws | ~> 4.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
+22 -24
View File
@@ -14,7 +14,7 @@ data "aws_availability_zones" "available" {
locals {
name = "ex-${replace(basename(path.cwd), "_", "-")}"
cluster_version = "1.33"
kubernetes_version = "1.33"
region = "eu-west-1"
vpc_cidr = "10.0.0.0/16"
@@ -34,27 +34,25 @@ locals {
module "eks" {
source = "../.."
cluster_name = local.name
cluster_version = local.cluster_version
cluster_endpoint_public_access = true
name = local.name
kubernetes_version = local.kubernetes_version
endpoint_public_access = true
enable_cluster_creator_admin_permissions = true
# Enable EFA support by adding necessary security group rules
# to the shared node security group
enable_efa_support = true
cluster_addons = {
addons = {
coredns = {
most_recent = true
}
eks-pod-identity-agent = {
before_compute = true
most_recent = true
}
kube-proxy = {
most_recent = true
}
vpc-cni = {
before_compute = true
most_recent = true
pod_identity_association = [{
role_arn = module.aws_vpc_cni_ipv4_pod_identity.iam_role_arn
@@ -69,12 +67,14 @@ module "eks" {
# External encryption key
create_kms_key = false
cluster_encryption_config = {
encryption_config = {
resources = ["secrets"]
provider_key_arn = module.kms.key_arn
}
self_managed_node_group_defaults = {
self_managed_node_groups = {
# Default node group - as provisioned by the module defaults
default_node_group = {
ami_type = "AL2023_x86_64_STANDARD"
ami_id = data.aws_ami.eks_default.image_id
@@ -85,10 +85,6 @@ module "eks" {
}
}
self_managed_node_groups = {
# Default node group - as provisioned by the module defaults
default_node_group = {}
# Bottlerocket node group
bottlerocket = {
name = "bottlerocket-self-mng"
@@ -153,6 +149,7 @@ module "eks" {
spot_allocation_strategy = "capacity-optimized"
}
launch_template = {
override = [
{
instance_type = "m5.large"
@@ -165,6 +162,7 @@ module "eks" {
]
}
}
}
# Complete
complete = {
@@ -232,8 +230,6 @@ module "eks" {
kubelet:
config:
shutdownGracePeriod: 30s
featureGates:
DisableKubeletCloudCredentialProviders: true
EOT
content_type = "application/node.eks.aws"
}]
@@ -263,6 +259,7 @@ module "eks" {
}
# ASG configuration
launch_template = {
override = [
{
instance_requirements = {
@@ -280,11 +277,12 @@ module "eks" {
]
}
}
}
metadata_options = {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 2
http_put_response_hop_limit = 1
instance_metadata_tags = "disabled"
}
@@ -334,7 +332,7 @@ module "eks" {
# This will:
# 1. Create a placement group to place the instances close to one another
# 2. Ignore subnets that reside in AZs that do not support the instance type
# 2. Create and attach the necessary security group rules (and security group)
# 3. Expose all of the available EFA interfaces on the launch template
enable_efa_support = true
enable_efa_only = true
@@ -378,7 +376,7 @@ module "disabled_self_managed_node_group" {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
@@ -420,7 +418,7 @@ data "aws_ami" "eks_default" {
filter {
name = "name"
values = ["amazon-eks-node-al2023-x86_64-standard-${local.cluster_version}-v*"]
values = ["amazon-eks-node-al2023-x86_64-standard-${local.kubernetes_version}-v*"]
}
}
@@ -430,7 +428,7 @@ data "aws_ami" "eks_default_bottlerocket" {
filter {
name = "name"
values = ["bottlerocket-aws-k8s-${local.cluster_version}-x86_64-*"]
values = ["bottlerocket-aws-k8s-${local.kubernetes_version}-x86_64-*"]
}
}
@@ -446,7 +444,7 @@ module "key_pair" {
module "ebs_kms_key" {
source = "terraform-aws-modules/kms/aws"
version = "~> 2.0"
version = "~> 4.0"
description = "Customer managed key to encrypt EKS managed node group volumes"
@@ -470,7 +468,7 @@ module "ebs_kms_key" {
module "kms" {
source = "terraform-aws-modules/kms/aws"
version = "~> 2.1"
version = "~> 4.0"
aliases = ["eks/${local.name}"]
description = "${local.name} cluster encryption key"
+2 -2
View File
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ $ terraform apply --auto-approve
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_local"></a> [local](#requirement\_local) | >= 2.4 |
## Providers
+13
View File
@@ -15,6 +15,7 @@ locals {
module "eks_mng_al2_disabled" {
source = "../../modules/_user_data"
ami_type = "AL2_x86_64"
create = false
}
@@ -22,6 +23,7 @@ module "eks_mng_al2_no_op" {
source = "../../modules/_user_data"
# Hard requirement
ami_type = "AL2_x86_64"
cluster_service_cidr = local.cluster_service_cidr
}
@@ -29,6 +31,7 @@ module "eks_mng_al2_additional" {
source = "../../modules/_user_data"
# Hard requirement
ami_type = "AL2_x86_64"
cluster_service_cidr = local.cluster_service_cidr
pre_bootstrap_user_data = <<-EOT
@@ -39,6 +42,7 @@ module "eks_mng_al2_additional" {
module "eks_mng_al2_custom_ami" {
source = "../../modules/_user_data"
ami_type = "AL2_x86_64"
cluster_name = local.name
cluster_endpoint = local.cluster_endpoint
cluster_auth_base64 = local.cluster_auth_base64
@@ -60,6 +64,7 @@ module "eks_mng_al2_custom_ami" {
module "eks_mng_al2_custom_ami_ipv6" {
source = "../../modules/_user_data"
ami_type = "AL2_x86_64"
cluster_name = local.name
cluster_endpoint = local.cluster_endpoint
cluster_auth_base64 = local.cluster_auth_base64
@@ -82,6 +87,7 @@ module "eks_mng_al2_custom_ami_ipv6" {
module "eks_mng_al2_custom_template" {
source = "../../modules/_user_data"
ami_type = "AL2_x86_64"
cluster_name = local.name
cluster_endpoint = local.cluster_endpoint
cluster_auth_base64 = local.cluster_auth_base64
@@ -364,12 +370,15 @@ module "self_mng_al2_no_op" {
is_eks_managed_node_group = false
# Hard requirement
ami_type = "AL2_x86_64"
cluster_service_cidr = local.cluster_service_cidr
}
module "self_mng_al2_bootstrap" {
source = "../../modules/_user_data"
ami_type = "AL2_x86_64"
enable_bootstrap_user_data = true
is_eks_managed_node_group = false
@@ -393,6 +402,8 @@ module "self_mng_al2_bootstrap" {
module "self_mng_al2_bootstrap_ipv6" {
source = "../../modules/_user_data"
ami_type = "AL2_x86_64"
enable_bootstrap_user_data = true
is_eks_managed_node_group = false
@@ -417,6 +428,8 @@ module "self_mng_al2_bootstrap_ipv6" {
module "self_mng_al2_custom_template" {
source = "../../modules/_user_data"
ami_type = "AL2_x86_64"
enable_bootstrap_user_data = true
is_eks_managed_node_group = false
+1 -1
View File
@@ -1,5 +1,5 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
local = {
+888 -108
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,14 +1,14 @@
terraform {
required_version = ">= 1.3.2"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.95, < 6.0.0"
version = ">= 6.0"
}
tls = {
source = "hashicorp/tls"
version = ">= 3.0"
version = ">= 4.0"
}
time = {
source = "hashicorp/time"