Skip to content

Commit e036f84

Browse files
authored
Merge pull request #8 from gitops-bridge-dev/external-secrets-example-2
External secrets example take 2
2 parents 5b03183 + 423a713 commit e036f84

File tree

8 files changed

+244
-82
lines changed

8 files changed

+244
-82
lines changed

argocd/iac/terraform/examples/eks/external-secrets/README.md

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,8 @@
22

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

5-
The example demonstrate how to use private git repository for workload apps.
6-
7-
The example stores your ssh key in AWS Secret Manager, and External Secret Operator to create the secret
8-
for ArgoCD to access the git repositories.
9-
10-
## Prerequisites
11-
- Create a Github ssh key file, example assumes the file path `~/.ssh/id_rsa`, update `main.tf` if using a different location
5+
The example demonstrate how to use [External Secret Operator(ESO)](https://external-secrets.io) with
6+
AWS Secret Manager and AWS Systems Manager Parameter Store
127

138
Deploy EKS Cluster
149
```shell
@@ -21,16 +16,16 @@ Access Terraform output to configure `kubectl` and `argocd`
2116
terraform output
2217
```
2318

24-
There is a file `github.yaml` located in the addons git repository `clusters/ex-external-secrets/secret/` this file creates the resources `ClusterSecretStore` and `ExternalSecret`. Update git url in this file when you change the git repository for the workloads specified in `bootstrap/workloads.yaml`. Also update the region in this file if you are using a different region for AWS Secret Manager.
25-
26-
To verify that the ArgoCD secret with ssh key is created run the following command
19+
Verify that the secrets `external-secrets-ps` and `external-secrets-sm` are present
2720
```shell
28-
kubectl get secret private-repo-creds -n argocd
21+
kubectl get secrets -n external-secrets
2922
```
23+
3024
Expected output, should have 3 data items in secret
3125
```
32-
NAME TYPE DATA AGE
33-
private-repo-creds Opaque 3 6m45s
26+
NAME TYPE DATA AGE
27+
external-secrets-ps Opaque 2 1m
28+
external-secrets-sm Opaque 2 1m
3429
```
3530

3631
Destroy EKS Cluster
Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,33 @@
1+
---
12
apiVersion: argoproj.io/v1alpha1
2-
kind: Application
3+
kind: ApplicationSet
34
metadata:
45
name: bootstrap-addons
5-
namespace: 'argocd'
6+
namespace: argocd
67
spec:
7-
destination:
8-
server: https://kubernetes.default.svc
9-
namespace: 'argocd'
10-
project: default
11-
source:
12-
path: ${path}
13-
repoURL: ${repoURL}
14-
targetRevision: ${targetRevision}
15-
directory:
16-
recurse: true
17-
exclude: exclude/*
188
syncPolicy:
19-
automated: {}
9+
preserveResourcesOnDeletion: true
10+
generators:
11+
- clusters:
12+
selector:
13+
matchExpressions:
14+
- key: akuity.io/argo-cd-cluster-name
15+
operator: NotIn
16+
values: [in-cluster]
17+
template:
18+
metadata:
19+
name: 'bootstrap-addons'
20+
spec:
21+
project: default
22+
source:
23+
repoURL: '{{metadata.annotations.gitops_bridge_repo_url}}'
24+
path: '{{metadata.annotations.gitops_bridge_repo_path}}'
25+
targetRevision: '{{metadata.annotations.gitops_bridge_repo_revision}}'
26+
directory:
27+
recurse: true
28+
exclude: exclude/*
29+
destination:
30+
namespace: 'argocd'
31+
name: '{{name}}'
32+
syncPolicy:
33+
automated: {}
Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,45 @@
1+
---
12
apiVersion: argoproj.io/v1alpha1
2-
kind: Application
3+
kind: ApplicationSet
34
metadata:
4-
name: bootstrap-workloads
5-
namespace: 'argocd'
6-
finalizers:
7-
- resources-finalizer.argocd.argoproj.io
5+
name: external-secrets-example
6+
namespace: argocd
87
spec:
9-
destination:
10-
server: https://kubernetes.default.svc
11-
namespace: 'guestbook'
12-
project: default
13-
source:
14-
path: helm-guestbook
15-
repoURL: git@github.com:argoproj/argocd-example-apps.git
16-
targetRevision: HEAD
178
syncPolicy:
18-
automated: {}
19-
syncOptions:
20-
- CreateNamespace=true
9+
preserveResourcesOnDeletion: true
10+
generators:
11+
- clusters:
12+
selector:
13+
matchExpressions:
14+
- key: akuity.io/argo-cd-cluster-name
15+
operator: NotIn
16+
values: [in-cluster]
17+
template:
18+
metadata:
19+
name: 'external-secrets-example'
20+
spec:
21+
project: default
22+
source:
23+
repoURL: '{{metadata.annotations.workload_repo_url}}'
24+
path: '{{metadata.annotations.workload_repo_path}}'
25+
targetRevision: '{{metadata.annotations.workload_repo_revision}}'
26+
helm:
27+
releaseName: 'external-secrets-example'
28+
values: |
29+
region: '{{metadata.annotations.aws_region}}'
30+
externalSecret:
31+
clusterSecretStore:
32+
secret: '{{metadata.annotations.workload_sm_secret}}'
33+
secretStore:
34+
secret: '{{metadata.annotations.workload_ps_secret}}'
35+
destination:
36+
namespace: '{{metadata.annotations.external_secrets_namespace}}'
37+
name: '{{name}}'
38+
syncPolicy:
39+
automated: {}
40+
retry:
41+
backoff:
42+
duration: 1m
43+
limit: 10
44+
syncOptions:
45+
- CreateNamespace=true
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: v2
2+
name: resources
3+
description: A Helm chart for Kubernetes
4+
5+
# A chart can be either an 'application' or a 'library' chart.
6+
#
7+
# Application charts are a collection of templates that can be packaged into versioned archives
8+
# to be deployed.
9+
#
10+
# Library charts provide useful utilities or functions for the chart developer. They're included as
11+
# a dependency of application charts to inject those utilities and functions into the rendering
12+
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
13+
type: application
14+
15+
# This is the chart version. This version number should be incremented each time you make changes
16+
# to the chart and its templates, including the app version.
17+
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18+
version: 1.0.0
19+
20+
# This is the version number of the application being deployed. This version number should be
21+
# incremented each time you make changes to the application. Versions are not expected to
22+
# follow Semantic Versioning. They should reflect the version the application is using.
23+
# It is recommended to use it with quotes.
24+
appVersion: "1.0.0"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
apiVersion: external-secrets.io/v1beta1
3+
kind: ClusterSecretStore
4+
metadata:
5+
name: cluster-secretstore-sm
6+
spec:
7+
provider:
8+
aws:
9+
service: SecretsManager
10+
region: {{ .Values.region }}
11+
---
12+
apiVersion: external-secrets.io/v1beta1
13+
kind: ExternalSecret
14+
metadata:
15+
name: external-secrets-sm
16+
spec:
17+
refreshInterval: 1h
18+
secretStoreRef:
19+
name: cluster-secretstore-sm
20+
kind: ClusterSecretStore
21+
dataFrom:
22+
- extract:
23+
key: {{ .Values.externalSecret.clusterSecretStore.secret }}
24+
---
25+
apiVersion: external-secrets.io/v1beta1
26+
kind: SecretStore
27+
metadata:
28+
name: secretstore-ps
29+
spec:
30+
provider:
31+
aws:
32+
service: ParameterStore
33+
region: {{ .Values.region }}
34+
---
35+
apiVersion: external-secrets.io/v1beta1
36+
kind: ExternalSecret
37+
metadata:
38+
name: external-secrets-ps
39+
spec:
40+
refreshInterval: 1h
41+
secretStoreRef:
42+
name: secretstore-ps
43+
kind: SecretStore
44+
dataFrom:
45+
- extract:
46+
key: {{ .Values.externalSecret.secretStore.secret }}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
region: us-west-2
2+
externalSecret:
3+
clusterSecretStore:
4+
secret: secret
5+
secretStore:
6+
secret: /external-secrets/secret

argocd/iac/terraform/examples/eks/external-secrets/main.tf

Lines changed: 64 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,36 @@ provider "kubernetes" {
4343
}
4444

4545
locals {
46-
name = "ex-${replace(basename(path.cwd), "_", "-")}"
47-
environment = "dev"
48-
region = "us-west-2"
49-
cluster_version = "1.27"
50-
gitops_url = var.gitops_url
51-
gitops_revision = var.gitops_revision
52-
gitops_path = var.gitops_path
46+
name = "ex-${replace(basename(path.cwd), "_", "-")}"
47+
environment = "dev"
48+
region = "us-west-2"
49+
cluster_version = "1.27"
50+
gitops_addons_org = var.gitops_addons_org
51+
gitops_addons_repo = var.gitops_addons_repo
52+
gitops_addons_path = var.gitops_addons_path
53+
gitops_addons_revision = var.gitops_addons_revision
54+
gitops_addons_url = "${local.gitops_addons_org}/${local.gitops_addons_repo}"
55+
56+
gitops_workload_org = var.gitops_workload_org
57+
gitops_workload_repo = var.gitops_workload_repo
58+
gitops_workload_path = var.gitops_workload_path
59+
gitops_workload_revision = var.gitops_workload_revision
60+
gitops_workload_url = "${local.gitops_workload_org}/${local.gitops_workload_repo}"
61+
62+
# Secret names in AWS
63+
workload_sm_secret = local.name
64+
workload_pm_secret = "/${local.name}/secret"
5365

54-
aws_secret_manager_secret_name = "argocd-ssh-key"
55-
git_private_ssh_key = "~/.ssh/id_rsa" # Update with the git ssh key to be used by ArgoCD
5666

5767
aws_addons = {
58-
enable_cert_manager = true
68+
#enable_cert_manager = true
5969
#enable_aws_efs_csi_driver = true
6070
#enable_aws_fsx_csi_driver = true
6171
#enable_aws_cloudwatch_metrics = true
6272
#enable_aws_privateca_issuer = true
6373
#enable_cluster_autoscaler = true
6474
#enable_external_dns = true
65-
enable_external_secrets = true
75+
enable_external_secrets = true
6676
#enable_aws_load_balancer_controller = true
6777
#enable_fargate_fluentbit = true
6878
#enable_aws_for_fluentbit = true
@@ -82,7 +92,7 @@ locals {
8292
#enable_ingress_nginx = true
8393
#enable_kyverno = true
8494
#enable_kube_prometheus_stack = true
85-
enable_metrics_server = true
95+
#enable_metrics_server = true
8696
#enable_prometheus_adapter = true
8797
#enable_secrets_store_csi_driver = true
8898
#enable_vpa = true
@@ -99,17 +109,23 @@ locals {
99109
aws_vpc_id = module.vpc.vpc_id
100110
},
101111
{
102-
gitops_bridge_repo_url = local.gitops_url
103-
gitops_bridge_repo_revision = local.gitops_revision
112+
gitops_bridge_repo_url = local.gitops_addons_url
113+
gitops_bridge_repo_path = local.gitops_addons_path
114+
gitops_bridge_repo_revision = local.gitops_addons_revision
115+
},
116+
{
117+
workload_repo_url = local.gitops_workload_url
118+
workload_repo_path = local.gitops_workload_path
119+
workload_repo_revision = local.gitops_workload_revision
120+
},
121+
{
122+
workload_sm_secret = aws_secretsmanager_secret.secret.name
123+
workload_ps_secret = aws_ssm_parameter.secret_parameter.name
104124
}
105125
)
106126

107127
argocd_bootstrap_app_of_apps = {
108-
addons = templatefile("${path.module}/bootstrap/addons.yaml", {
109-
repoURL = local.gitops_url
110-
targetRevision = local.gitops_revision
111-
path = local.gitops_path
112-
})
128+
addons = file("${path.module}/bootstrap/addons.yaml")
113129
workloads = file("${path.module}/bootstrap/workloads.yaml")
114130
}
115131

@@ -122,6 +138,35 @@ locals {
122138
}
123139
}
124140

141+
################################################################################
142+
# Secret Manager & Parameter Store
143+
################################################################################
144+
resource "aws_kms_key" "secrets" {
145+
enable_key_rotation = true
146+
}
147+
resource "aws_secretsmanager_secret" "secret" {
148+
name = local.workload_sm_secret
149+
recovery_window_in_days = 0
150+
kms_key_id = aws_kms_key.secrets.arn
151+
}
152+
resource "aws_secretsmanager_secret_version" "secret" {
153+
secret_id = aws_secretsmanager_secret.secret.id
154+
secret_string = jsonencode({
155+
username = "secretuser",
156+
password = "secretpassword"
157+
})
158+
}
159+
resource "aws_ssm_parameter" "secret_parameter" {
160+
name = local.workload_pm_secret
161+
type = "SecureString"
162+
value = jsonencode({
163+
username = "secretuser",
164+
password = "secretpassword"
165+
})
166+
key_id = aws_kms_key.secrets.arn
167+
}
168+
169+
125170
################################################################################
126171
# GitOps Bridge: Metadata
127172
################################################################################
@@ -144,20 +189,6 @@ module "gitops_bridge_bootstrap" {
144189
argocd_bootstrap_app_of_apps = local.argocd_bootstrap_app_of_apps
145190
}
146191

147-
################################################################################
148-
# AWS Secret Manager
149-
################################################################################
150-
#tfsec:ignore:aws-ssm-secret-use-customer-key
151-
resource "aws_secretsmanager_secret" "git_ssh_key" {
152-
name = local.aws_secret_manager_secret_name
153-
recovery_window_in_days = 0 # Set to zero for this example to force delete during Terraform destroy
154-
}
155-
resource "aws_secretsmanager_secret_version" "git_ssh_key" {
156-
secret_id = aws_secretsmanager_secret.git_ssh_key.id
157-
secret_string = file(pathexpand(local.git_private_ssh_key))
158-
}
159-
160-
161192
################################################################################
162193
# EKS Blueprints Addons
163194
################################################################################

0 commit comments

Comments
 (0)