Initial commit from kro/examples/aws/eks-cluster-mgmt

This commit is contained in:
2026-04-21 09:55:53 -03:00
parent 0585444299
commit 7d11fd5889
66 changed files with 3667 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
# Local .terraform directories
**/.terraform/*
.terraform.lock.hcl
# .tfstate files
*.tfstate
*.tfstate.*
tfstate.*
# Crash log files
crash.log
# Exclude all .tfvars files, which might contain sensitive data, such as
# password, private keys, and other secrets.
# Ignore override files as they are usually used to override resources locally.
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc
backend.hcl
# Ignore log files
*.log
# Ignore temporary files
*.tmp
*.temp
.envrc
+58
View File
@@ -0,0 +1,58 @@
# Create ArgoCD namespace
resource "kubernetes_namespace_v1" "argocd" {
metadata {
name = local.argocd_namespace
}
}
locals {
cluster_name = module.eks.cluster_name
argocd_labels = merge({
cluster_name = local.cluster_name
environment = local.environment
"argocd.argoproj.io/secret-type" = "cluster"
},
try(local.addons, {})
)
argocd_annotations = merge(
{
cluster_name = local.cluster_name
environment = local.environment
},
try(local.addons_metadata, {})
)
}
locals {
config = <<-EOT
{
"tlsClientConfig": {
"insecure": false
}
}
EOT
argocd = {
apiVersion = "v1"
kind = "Secret"
metadata = {
name = module.eks.cluster_name
namespace = local.argocd_namespace
annotations = local.argocd_annotations
labels = local.argocd_labels
}
stringData = {
name = module.eks.cluster_name
server = module.eks.cluster_arn
project = "default"
}
}
}
resource "kubernetes_secret_v1" "cluster" {
metadata {
name = local.argocd.metadata.name
namespace = local.argocd.metadata.namespace
annotations = local.argocd.metadata.annotations
labels = local.argocd.metadata.labels
}
data = local.argocd.stringData
}
@@ -0,0 +1,31 @@
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: bootstrap
namespace: argocd
spec:
goTemplate: true
syncPolicy:
preserveResourcesOnDeletion: false # to be able to cleanup
generators:
- clusters:
selector:
matchLabels:
fleet_member: control-plane
template:
metadata:
name: bootstrap
spec:
project: default
source:
repoURL: '{{.metadata.annotations.fleet_repo_url}}'
path: '{{.metadata.annotations.fleet_repo_basepath}}{{.metadata.annotations.fleet_repo_path}}'
targetRevision: '{{.metadata.annotations.fleet_repo_revision}}'
directory:
recurse: false
exclude: exclude/*
destination:
namespace: 'argocd'
name: '{{.name}}'
syncPolicy:
automated: {}
+18
View File
@@ -0,0 +1,18 @@
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
data "aws_availability_zones" "available" {
# Do not include local zones
filter {
name = "opt-in-status"
values = ["opt-in-not-required"]
}
}
data "aws_ecr_authorization_token" "token" {}
data "aws_iam_session_context" "current" {
# This data source provides information on the IAM source role of an STS assumed role
# For non-role ARNs, this data source simply passes the ARN through issuer ARN
# Ref https://github.com/terraform-aws-modules/terraform-aws-eks/issues/2327#issuecomment-1355581682
# Ref https://github.com/hashicorp/terraform-provider-aws/issues/28381
arn = data.aws_caller_identity.current.arn
}
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
#if var not exit provide default
TF_VAR_FILE=${TF_VAR_FILE:-"terraform.tfvars"}
terraform init
terraform destroy -var-file=$TF_VAR_FILE
+153
View File
@@ -0,0 +1,153 @@
# IAM role for ACK controllers with assume role capability
resource "aws_iam_role" "ack_controller" {
name = "${local.name}-ack-controller"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "capabilities.eks.amazonaws.com"
}
Action = [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
})
tags = local.tags
}
# IAM policy allowing the role to assume any role
resource "aws_iam_policy" "ack_assume_role" {
name = "${local.name}-ack-assume-role"
description = "Policy allowing ACK controller to assume any role"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"sts:AssumeRole",
"sts:TagSession"
]
Resource = "*"
}
]
})
tags = local.tags
}
# Attach the assume role policy to the ACK controller role
resource "aws_iam_role_policy_attachment" "ack_assume_role" {
role = aws_iam_role.ack_controller.name
policy_arn = aws_iam_policy.ack_assume_role.arn
}
# Grant ACK controller role admin access to EKS cluster
resource "aws_eks_access_entry" "ack_controller" {
cluster_name = module.eks.cluster_name
principal_arn = aws_iam_role.ack_controller.arn
type = "STANDARD"
}
resource "aws_eks_access_policy_association" "ack_controller_admin" {
cluster_name = module.eks.cluster_name
principal_arn = aws_iam_role.ack_controller.arn
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope {
type = "cluster"
}
depends_on = [aws_eks_access_entry.ack_controller]
}
# IAM role for kro capability
resource "aws_iam_role" "kro_controller" {
name = "${local.name}-kro-controller"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "capabilities.eks.amazonaws.com"
}
Action = [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
})
tags = local.tags
}
# Grant kro controller role admin access to EKS cluster
resource "aws_eks_access_entry" "kro_controller" {
cluster_name = module.eks.cluster_name
principal_arn = aws_iam_role.kro_controller.arn
type = "STANDARD"
}
resource "aws_eks_access_policy_association" "kro_controller_admin" {
cluster_name = module.eks.cluster_name
principal_arn = aws_iam_role.kro_controller.arn
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope {
type = "cluster"
}
depends_on = [aws_eks_access_entry.kro_controller]
}
# IAM role for argocd capability
resource "aws_iam_role" "argocd_controller" {
name = "${local.name}-argocd-controller"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "capabilities.eks.amazonaws.com"
}
Action = [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
})
tags = local.tags
}
# Grant argocd controller role admin access to EKS cluster
resource "aws_eks_access_entry" "argocd_controller" {
cluster_name = module.eks.cluster_name
principal_arn = aws_iam_role.argocd_controller.arn
type = "STANDARD"
}
resource "aws_eks_access_policy_association" "argocd_controller_admin" {
cluster_name = module.eks.cluster_name
principal_arn = aws_iam_role.argocd_controller.arn
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope {
type = "cluster"
}
depends_on = [aws_eks_access_entry.argocd_controller]
}
+55
View File
@@ -0,0 +1,55 @@
module "eks" {
#checkov:skip=CKV_TF_1:We are using version control for those modules
#checkov:skip=CKV_TF_2:We are using version control for those modules
source = "terraform-aws-modules/eks/aws"
version = "~> 21.10.1"
name = local.name
kubernetes_version = local.cluster_version
endpoint_public_access = true
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
enable_cluster_creator_admin_permissions = true
compute_config = {
enabled = true
node_pools = ["general-purpose", "system"]
}
tags = {
Blueprint = local.name
GithubRepo = "https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest"
}
}
################################################################################
# Supporting Resources
################################################################################
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
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
# Tags subnets for Karpenter auto-discovery
"karpenter.sh/discovery" = local.name
}
tags = local.tags
}
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
#if var not exit provide default
TF_VAR_FILE=${TF_VAR_FILE:-"terraform.tfvars"}
terraform init
terraform apply -var-file=$TF_VAR_FILE
+95
View File
@@ -0,0 +1,95 @@
locals {
cluster_info = module.eks
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 2)
enable_automode = var.enable_automode
use_ack = var.use_ack
enable_efs = var.enable_efs
name = var.cluster_name
environment = var.environment
fleet_member = "control-plane"
tenant = var.tenant
region = data.aws_region.current.id
cluster_version = var.kubernetes_version
argocd_namespace = "argocd"
gitops_addons_repo_url = "https://github.com/${var.git_org_name}/${var.gitops_addons_repo_name}.git"
gitops_fleet_repo_url = "https://github.com/${var.git_org_name}/${var.gitops_fleet_repo_name}.git"
external_secrets = {
namespace = "external-secrets"
service_account = "external-secrets-sa"
}
aws_addons = {
enable_external_secrets = try(var.addons.enable_external_secrets, false)
enable_kro_eks_rgs = try(var.addons.enable_kro_eks_rgs, false)
enable_multi_acct = try(var.addons.enable_multi_acct, false)
}
oss_addons = {
}
addons = merge(
local.aws_addons,
local.oss_addons,
{ tenant = local.tenant },
{ fleet_member = local.fleet_member },
{ kubernetes_version = local.cluster_version },
{ aws_cluster_name = local.cluster_info.cluster_name },
)
addons_metadata = merge(
{
aws_cluster_name = local.cluster_info.cluster_name
aws_region = local.region
aws_account_id = data.aws_caller_identity.current.account_id
aws_vpc_id = module.vpc.vpc_id
use_ack = local.use_ack
},
{
addons_repo_url = local.gitops_addons_repo_url
addons_repo_path = var.gitops_addons_repo_path
addons_repo_basepath = var.gitops_addons_repo_base_path
addons_repo_revision = var.gitops_addons_repo_revision
},
{
fleet_repo_url = local.gitops_fleet_repo_url
fleet_repo_path = var.gitops_fleet_repo_path
fleet_repo_basepath = var.gitops_fleet_repo_base_path
fleet_repo_revision = var.gitops_fleet_repo_revision
},
{
external_secrets_namespace = local.external_secrets.namespace
external_secrets_service_account = local.external_secrets.service_account
}
)
argocd_apps = {
applicationsets = file("${path.module}/bootstrap/applicationsets.yaml")
}
role_arns = []
# # Generate dynamic access entries for each admin rolelocals {
admin_access_entries = {
for role_arn in local.role_arns : role_arn => {
principal_arn = role_arn
policy_associations = {
admins = {
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope = {
type = "cluster"
}
}
}
}
}
# Merging dynamic entries with static entries if needed
access_entries = merge({}, local.admin_access_entries)
tags = {
Blueprint = local.name
GithubRepo = "github.com/gitops-bridge-dev/gitops-bridge"
}
}
+23
View File
@@ -0,0 +1,23 @@
# Output the ACK controller role ARN
output "ack_controller_role_arn" {
description = "ARN of the IAM role for ACK controller"
value = aws_iam_role.ack_controller.arn
}
# Output the kro controller role ARN
output "kro_controller_role_arn" {
description = "ARN of the IAM role for kro controller"
value = aws_iam_role.kro_controller.arn
}
# Output the argocd controller role ARN
output "argocd_controller_role_arn" {
description = "ARN of the IAM role for argocd controller"
value = aws_iam_role.argocd_controller.arn
}
# Output cluster name
output "cluster_name" {
description = "Name of the EKS cluster"
value = module.eks.cluster_name
}
+34
View File
@@ -0,0 +1,34 @@
################################################################################
# External Secrets EKS Access
################################################################################
module "external_secrets_pod_identity" {
count = local.aws_addons.enable_external_secrets ? 1 : 0
source = "terraform-aws-modules/eks-pod-identity/aws"
version = "~> 1.4.0"
name = "external-secrets"
attach_external_secrets_policy = true
external_secrets_kms_key_arns = ["arn:aws:kms:${local.region}:*:key/${local.cluster_info.cluster_name}/*"]
external_secrets_secrets_manager_arns = ["arn:aws:secretsmanager:${local.region}:*:secret:${local.cluster_info.cluster_name}/*"]
external_secrets_ssm_parameter_arns = ["arn:aws:ssm:${local.region}:*:parameter/${local.cluster_info.cluster_name}/*"]
external_secrets_create_permission = false
attach_custom_policy = true
policy_statements = [
{
sid = "ecr"
actions = ["ecr:*"]
resources = ["*"]
}
]
# Pod Identity Associations
associations = {
addon = {
cluster_name = local.cluster_info.cluster_name
namespace = local.external_secrets.namespace
service_account = local.external_secrets.service_account
}
}
tags = local.tags
}
+39
View File
@@ -0,0 +1,39 @@
provider "helm" {
kubernetes {
host = local.cluster_info.cluster_endpoint
cluster_ca_certificate = base64decode(local.cluster_info.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = [
"eks",
"get-token",
"--cluster-name", local.cluster_info.cluster_name,
"--region", local.region
]
}
}
}
provider "kubernetes" {
host = local.cluster_info.cluster_endpoint
cluster_ca_certificate = base64decode(local.cluster_info.cluster_certificate_authority_data)
# insecure = true
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = [
"eks",
"get-token",
"--cluster-name", local.cluster_info.cluster_name,
"--region", local.region
]
}
}
provider "aws" {
}
+19
View File
@@ -0,0 +1,19 @@
vpc_name = "hub-cluster"
kubernetes_version = "1.34"
cluster_name = "hub-cluster"
tenant = "tenant1"
git_org_name = "XXXXXXXX" # update this if you want to customize the gitops configurations
gitops_addons_repo_name = "eks-cluster-mgmt"
gitops_addons_repo_base_path = "addons/"
gitops_addons_repo_path = "bootstrap"
gitops_addons_repo_revision = "main"
gitops_fleet_repo_name = "eks-cluster-mgmt"
gitops_fleet_repo_base_path = "fleet/"
gitops_fleet_repo_path = "bootstrap"
gitops_fleet_repo_revision = "main"
# AWS Accounts used for demo purposes (cluster1 cluster2)
account_ids = "012345678910 123456789101" # update this with your spoke aws accounts ids
+142
View File
@@ -0,0 +1,142 @@
variable "vpc_name" {
description = "VPC name to be used by pipelines for data"
type = string
}
variable "kubernetes_version" {
description = "Kubernetes version"
type = string
default = "1.34"
}
variable "github_app_credentilas_secret" {
description = "The name of the Secret storing github app credentials"
type = string
default = ""
}
variable "kms_key_admin_roles" {
description = "list of role ARNs to add to the KMS policy"
type = list(string)
default = []
}
variable "addons" {
description = "Kubernetes addons"
type = any
default = {
enable_external_secrets = true
enable_kro_eks_rgs = true
enable_multi_acct = true
}
}
variable "manifests" {
description = "Kubernetes manifests"
type = any
default = {}
}
variable "enable_addon_selector" {
description = "select addons using cluster selector"
type = bool
default = false
}
variable "route53_zone_name" {
description = "The route53 zone for external dns"
default = ""
}
# Github Repos Variables
variable "git_org_name" {
description = "The name of Github organisation"
default = "kro-run"
}
variable "gitops_addons_repo_name" {
description = "The name of git repo"
default = "kro"
}
variable "gitops_addons_repo_path" {
description = "The path of addons bootstraps in the repo"
default = "bootstrap"
}
variable "gitops_addons_repo_base_path" {
description = "The base path of addons in the repon"
default = "examples/aws/eks-cluster-mgmt/addons/"
}
variable "gitops_addons_repo_revision" {
description = "The name of branch or tag"
default = "main"
}
# Fleet
variable "gitops_fleet_repo_name" {
description = "The name of Git repo"
default = "kro"
}
variable "gitops_fleet_repo_path" {
description = "The path of fleet bootstraps in the repo"
default = "bootstrap"
}
variable "gitops_fleet_repo_base_path" {
description = "The base path of fleet in the repon"
default = "examples/aws/eks-cluster-mgmt/fleet/"
}
variable "gitops_fleet_repo_revision" {
description = "The name of branch or tag"
default = "main"
}
variable "ackCreate" {
description = "Creating PodIdentity and addons relevant resources with ACK"
default = false
}
variable "enable_efs" {
description = "Enabling EFS file system"
type = bool
default = false
}
variable "enable_automode" {
description = "Enabling Automode Cluster"
type = bool
default = true
}
variable "cluster_name" {
description = "Name of the cluster"
type = string
default = "hub-cluster"
}
variable "use_ack" {
description = "Defining to use ack or terraform for pod identity if this is true then we will use this label to deploy resources with ack"
type = bool
default = true
}
variable "environment" {
description = "Name of the environment for the Hub Cluster"
type = string
default = "control-plane"
}
variable "tenant" {
description = "Name of the tenant for the Hub Cluster"
type = string
default = "control-plane"
}
variable "account_ids" {
description = "List of aws accounts ACK will need to connect to"
type = string
default = ""
}
+18
View File
@@ -0,0 +1,18 @@
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.27.0"
}
helm = {
source = "hashicorp/helm"
version = "~> 3.1.1"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "3.0.1"
}
}
}