Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions argocd/iac/terraform/examples/eks/private-git/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ArgoCD on Amazon EKS

This example shows how to deploy Amazon EKS with addons configured via ArgoCD

The example demonstrate how to use private git repository for addons and workload.

The example reads your private ssh key, and creates two secretes to access the git repository for addons and another one for workloads

## Prerequisites
- Create a Github ssh key file, example assumes the file path `~/.ssh/id_rsa`, update `main.tf` if using a different location

Deploy EKS Cluster
```shell
terraform init
terraform apply
```

Access Terraform output to configure `kubectl` and `argocd`
```shell
terraform output
```

Destroy EKS Cluster
```shell
cd hub
./destroy.sh
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: bootstrap-addons
namespace: 'argocd'
spec:
destination:
server: https://kubernetes.default.svc
namespace: 'argocd'
project: default
source:
path: ${path}
repoURL: ${repoURL}
targetRevision: ${targetRevision}
directory:
recurse: true
exclude: exclude/*
syncPolicy:
automated: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: bootstrap-workloads
namespace: 'argocd'
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
server: https://kubernetes.default.svc
namespace: 'guestbook'
project: default
source:
path: ${path}
repoURL: ${repoURL}
targetRevision: ${targetRevision}
syncPolicy:
automated: {}
syncOptions:
- CreateNamespace=true
16 changes: 16 additions & 0 deletions argocd/iac/terraform/examples/eks/private-git/destroy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

set -x

# Delete the Ingress/SVC before removing the addons
TMPFILE=$(mktemp)
terraform output -raw configure_kubectl > "$TMPFILE"
source "$TMPFILE"

kubectl delete svc -n argocd argo-cd-argocd-server

terraform destroy -target="module.gitops_bridge_bootstrap" -auto-approve
terraform destroy -target="module.eks_blueprints_addons" -auto-approve
terraform destroy -target="module.eks" -auto-approve
terraform destroy -target="module.vpc" -auto-approve
terraform destroy -auto-approve
299 changes: 299 additions & 0 deletions argocd/iac/terraform/examples/eks/private-git/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
provider "aws" {
region = local.region
}
data "aws_caller_identity" "current" {}
data "aws_availability_zones" "available" {}

provider "helm" {
kubernetes {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.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", module.eks.cluster_name, "--region", local.region]
}
}
}

provider "kubectl" {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name, "--region", local.region]
command = "aws"
}
load_config_file = false
apply_retry_count = 15
}

provider "kubernetes" {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.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", module.eks.cluster_name, "--region", local.region]
}
}

locals {
name = "ex-${replace(basename(path.cwd), "_", "-")}"
environment = "dev"
region = "us-west-2"
cluster_version = "1.27"

git_private_ssh_key = "~/.ssh/id_rsa" # Update with the git ssh key to be used by ArgoCD

gitops_addons_org = "git@github.com:gitops-bridge-dev"
gitops_addons_repo = "gitops-bridge-argocd-control-plane-template"
gitops_addon_path = "bootstrap/control-plane/addons"
gitops_addon_revision = "HEAD"

gitops_workloads_org = "git@github.com:argoproj"
gitops_workloads_repo = "argocd-example-apps"
gitops_workloads_path = "helm-guestbook"
gitops_workloads_revision = "HEAD"

aws_addons = {
enable_cert_manager = true
#enable_aws_efs_csi_driver = true
#enable_aws_fsx_csi_driver = true
#enable_aws_cloudwatch_metrics = true
#enable_aws_privateca_issuer = true
#enable_cluster_autoscaler = true
#enable_external_dns = true
#enable_external_secrets = true
#enable_aws_load_balancer_controller = true
#enable_fargate_fluentbit = true
#enable_aws_for_fluentbit = true
#enable_aws_node_termination_handler = true
#enable_karpenter = true
#enable_velero = true
#enable_aws_gateway_api_controller = true
#enable_aws_ebs_csi_resources = true # generate gp2 and gp3 storage classes for ebs-csi
#enable_aws_secrets_store_csi_driver_provider = true
}
oss_addons = {
#enable_argo_rollouts = true
#enable_argo_workflows = true
#enable_cluster_proportional_autoscaler = true
#enable_gatekeeper = true
#enable_gpu_operator = true
#enable_ingress_nginx = true
#enable_kyverno = true
#enable_kube_prometheus_stack = true
enable_metrics_server = true
#enable_prometheus_adapter = true
#enable_secrets_store_csi_driver = true
#enable_vpa = true
#enable_foo = true # you can add any addon here, make sure to update the gitops repo with the corresponding application set
}
addons = merge(local.aws_addons, local.oss_addons, { kubernetes_version = local.cluster_version })

addons_metadata = merge(
module.eks_blueprints_addons.gitops_metadata,
{
aws_cluster_name = module.eks.cluster_name
aws_region = local.region
aws_account_id = data.aws_caller_identity.current.account_id
aws_vpc_id = module.vpc.vpc_id
},
{
gitops_bridge_repo_url = "${local.gitops_addons_org}/${local.gitops_addons_repo}"
gitops_bridge_repo_revision = local.gitops_addon_revision
}
)

argocd_bootstrap_app_of_apps = {
addons = templatefile("${path.module}/bootstrap/addons.yaml", {
repoURL = "${local.gitops_addons_org}/${local.gitops_addons_repo}"
path = local.gitops_addon_path
targetRevision = local.gitops_addon_revision
})
workloads = templatefile("${path.module}/bootstrap/workloads.yaml", {
repoURL = "${local.gitops_workloads_org}/${local.gitops_workloads_repo}"
path = local.gitops_workloads_path
targetRevision = local.gitops_workloads_revision
})
}

vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)

tags = {
Blueprint = local.name
GithubRepo = "github.com/csantanapr/terraform-gitops-bridge"
}
}

################################################################################
# GitOps Bridge: Private ssh keys for git
################################################################################
resource "kubernetes_namespace" "argocd" {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got some issues with several terraform apply complaining that the namespace already exists..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the namespace should not exist, in the bootstrap I added for the helm to not create the namespace because it already exists

module "gitops_bridge_bootstrap" {
  source = "../../../modules/gitops-bridge-bootstrap"

  argocd_cluster               = module.gitops_bridge_metadata.argocd
  argocd_bootstrap_app_of_apps = local.argocd_bootstrap_app_of_apps
  argocd = { create_namespace = false }
  depends_on = [kubernetes_secret.git_secrets]
}

the argocd = { create_namespace = false }

Copy link
Member Author

@csantanapr csantanapr Aug 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what I'm having trouble is with the destroy now of the namespace
need to look how to handle

depends_on = [ module.eks_blueprints_addons ]
metadata {
name = "argocd"
}
}
resource "kubernetes_secret" "git_secrets" {
depends_on = [ kubernetes_namespace.argocd ]
for_each = {
git-addons = {
type = "git"
url = local.gitops_addons_org
sshPrivateKey = file(pathexpand(local.git_private_ssh_key))
}
git-workloads = {
type = "git"
url = local.gitops_addons_org

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be gitops_workloads_org

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops

sshPrivateKey = file(pathexpand(local.git_private_ssh_key))
}
}
metadata {
name = each.key
namespace = kubernetes_namespace.argocd.metadata[0].name
labels = {
"argocd.argoproj.io/secret-type" = "repo-creds"
}
}
data = each.value
}

################################################################################
# GitOps Bridge: Metadata
################################################################################
module "gitops_bridge_metadata" {
source = "../../../modules/gitops-bridge-metadata"

cluster_name = module.eks.cluster_name
environment = local.environment
metadata = local.addons_metadata
addons = local.addons
}

################################################################################
# GitOps Bridge: Bootstrap
################################################################################
module "gitops_bridge_bootstrap" {
source = "../../../modules/gitops-bridge-bootstrap"

argocd_cluster = module.gitops_bridge_metadata.argocd
argocd_bootstrap_app_of_apps = local.argocd_bootstrap_app_of_apps
argocd = { create_namespace = false }
depends_on = [kubernetes_secret.git_secrets]
}


################################################################################
# EKS Blueprints Addons
################################################################################
module "eks_blueprints_addons" {
source = "aws-ia/eks-blueprints-addons/aws"
version = "~> 1.0"

cluster_name = module.eks.cluster_name
cluster_endpoint = module.eks.cluster_endpoint
cluster_version = module.eks.cluster_version
oidc_provider_arn = module.eks.oidc_provider_arn

# Using GitOps Bridge
create_kubernetes_resources = false

# EKS Blueprints Addons
enable_cert_manager = try(local.aws_addons.enable_cert_manager, false)
enable_aws_efs_csi_driver = try(local.aws_addons.enable_aws_efs_csi_driver, false)
enable_aws_fsx_csi_driver = try(local.aws_addons.enable_aws_fsx_csi_driver, false)
enable_aws_cloudwatch_metrics = try(local.aws_addons.enable_aws_cloudwatch_metrics, false)
enable_aws_privateca_issuer = try(local.aws_addons.enable_aws_privateca_issuer, false)
enable_cluster_autoscaler = try(local.aws_addons.enable_cluster_autoscaler, false)
enable_external_dns = try(local.aws_addons.enable_external_dns, false)
enable_external_secrets = try(local.aws_addons.enable_external_secrets, false)
enable_aws_load_balancer_controller = try(local.aws_addons.enable_aws_load_balancer_controller, false)
enable_fargate_fluentbit = try(local.aws_addons.enable_fargate_fluentbit, false)
enable_aws_for_fluentbit = try(local.aws_addons.enable_aws_for_fluentbit, false)
enable_aws_node_termination_handler = try(local.aws_addons.enable_aws_node_termination_handler, false)
enable_karpenter = try(local.aws_addons.enable_karpenter, false)
enable_velero = try(local.aws_addons.enable_velero, false)
enable_aws_gateway_api_controller = try(local.aws_addons.enable_aws_gateway_api_controller, false)

tags = local.tags
}

################################################################################
# EKS Cluster
################################################################################
#tfsec:ignore:aws-eks-enable-control-plane-logging
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 19.13"

cluster_name = local.name
cluster_version = local.cluster_version
cluster_endpoint_public_access = true


vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets

eks_managed_node_groups = {
initial = {
instance_types = ["t3.medium"]

min_size = 3
max_size = 10
desired_size = 3
}
}
# EKS Addons
cluster_addons = {
vpc-cni = {
# Specify the VPC CNI addon should be deployed before compute to ensure
# the addon is configured before data plane compute resources are created
# See README for further details
before_compute = true
most_recent = true # To ensure access to the latest settings provided
configuration_values = jsonencode({
env = {
# Reference docs https://docs.aws.amazon.com/eks/latest/userguide/cni-increase-ip-addresses.html
ENABLE_PREFIX_DELEGATION = "true"
WARM_PREFIX_TARGET = "1"
}
})
}
}
tags = local.tags
}

################################################################################
# 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 = local.tags
}
Loading