FluxCD Add-on¶
This add-on installs fluxcd.
Flux is a declarative, GitOps-based continuous delivery tool that can be integrated into any CI/CD pipeline. The ability to manage deployments to multiple remote Kubernetes clusters from a central management cluster, support for progressive delivery, and multi-tenancy are some of the notable features of Flux.
Usage¶
Only specify unique values for the repository and bucket name
field.
Single bootstrap repo path¶
import * as cdk from 'aws-cdk-lib';
import * as blueprints from '@aws-quickstart/eks-blueprints';
const app = new cdk.App();
const addOn = new blueprints.addons.FluxCDAddOn({
repositories:[{
name: "aws-observability-accelerator",
namespace: undefined,
repository: {
repoUrl: 'https://github.com/aws-observability/aws-observability-accelerator',
targetRevision: "main",
},
values: {
"region": "us-east-2"
},
kustomizations: [{kustomizationPath: "./artifacts/grafana-operator-manifests/eks/infrastructure"}],
}],
})
...
const blueprint = blueprints.EksBlueprint.builder()
.addOns(addOn)
.build(app, 'my-stack-name');
Multiple bootstrap repo paths¶
Multiple bootstrap repo paths are useful when you want to create multiple Kustomizations, pointing to different paths, e.g. to deploy manifests from specific subfolders in your repository:
import * as cdk from 'aws-cdk-lib';
import * as blueprints from '@aws-quickstart/eks-blueprints';
const app = new cdk.App();
const addOn = new blueprints.addons.FluxCDAddOn({
repositories: [{
name: "aws-observability-accelerator",
namespace: undefined,
repository: {
repoUrl: 'https://github.com/aws-observability/aws-observability-accelerator',
targetRevision: "main",
},
values: {
"region": "us-east-2"
},
kustomizations: [{kustomizationPath:"./artifacts/grafana-operator-manifests/eks/infrastructure"}, {kustomizationPath: "./artifacts/grafana-operator-manifests/eks/java"}]
}],
})
...
const blueprint = blueprints.EksBlueprint.builder()
.version("auto")
.addOns(addOn)
.build(app, 'my-stack-name');
Single bootstrap S3 bucket repository¶
import * as cdk from 'aws-cdk-lib';
import * as blueprints from '@aws-quickstart/eks-blueprints';
import * as s3 from 'aws-cdk-lib/aws-s3';
const app = new cdk.App();
const fluxBootstrap = new s3.Bucket(this, "FluxBootstrap", {
removalPolicy: cdk.RemovalPolicy.RETAIN,
});
const addOn = new blueprints.addons.FluxCDAddOn({
buckets: [{
name: "bootstrap-bucket",
bucketName: fluxBootstrap.bucketName,
bucketRegion: cdk.Aws.REGION,
}],
})
...
const blueprint = blueprints.EksBlueprint.builder()
.addOns(addOn)
.build(app, 'my-stack-name');
By default the FluxCD source-controller attempts to access the S3 bucket by using the IAM instance profile.
To grant access assign node group instances IAM role granting read access to the S3 bucket.
Alternatively reference to a Secret containing the accesskey
and secretkey
values with the secretRef
parameter to authenticate using IAM user authentication.
See FluxCD Bucket Source Controller documentation.
Workload Repositories¶
- To add workload repositories as well as the bootstrap repository, please follow this example below
import * as cdk from 'aws-cdk-lib';
import * as blueprints from '@aws-quickstart/eks-blueprints';
const app = new cdk.App();
const nginxDashUrl = "https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/grafana-dashboards/eks/nginx/nginx.json"
const javaDashUrl = "https://raw.githubusercontent.com/aws-observability/aws-observability-accelerator/main/artifacts/grafana-dashboards/eks/java/default.json"
const addOn = new blueprints.addons.FluxCDAddOn({
repositories: [
{
name: "aws-observability-accelerator",
namespace: undefined,
repository: {
repoUrl: 'https://github.com/aws-observability/aws-observability-accelerator',
targetRevision: "main",
},
values: {
"GRAFANA_NGINX_DASH_URL" : nginxDashUrl,
"GRAFANA_JAVA_JMX_DASH_URL": javaDashUrl,
},
kustomizations: [{kustomizationPath:"./artifacts/grafana-operator-manifests/eks/infrastructure"}, {kustomizationPath: "./artifacts/grafana-operator-manifests/eks/java"}]
},
{
name: "podinfo",
namespace: undefined,
repository: {
repoUrl: 'https://github.com/stefanprodan/podinfo',
targetRevision: "master",
},
values: {
"region": "us-east-2"
},
kustomizations: [{kustomizationPath: "./kustomize", kustomizationTargetNamespace: "default"}],
}
],
});
const blueprint = blueprints.EksBlueprint.builder()
.version("auto")
.addOns(
new blueprints.addons.GrafanaOperatorAddon,
addOn,
)
.build(app, 'my-stack-name');
Secret Management for private Git repositories with FluxCD¶
Please follow the below steps if you are looking to setup FluxCD addon to read secrets and sync private Git repos.
Note that different git servers may require different authentication methods. For example, GitHub requires a basic access token, while others may require a bearer token. For more information, refer to the FluxCD documentation.
- Please use the following CLI command to create an AWS Secrets Manager secret for
basic-access-auth
.
export SECRET_NAME=basic-access-auth
export GIT_USERNAME=<YOUR_GIT_USERNAME>
export GIT_TOKEN=<YOUR_GIT_TOKEN>
export AWS_REGION=<YOUR_AWS_REGION>
aws secretsmanager create-secret \
--name $SECRET_NAME \
--description "Your GIT BASIC ACCESS SECRET" \
--secret-string "{ 'username': '${GIT_USERNAME}', 'password': '${GIT_TOKEN}' }" \
--region $AWS_REGION
- Below is the snippet showing the usage of adding
ExternalsSecretsAddOn
to read secrets from AWS Secrets Manager and configuringFluxCDAddOn
to read private repositories.
import * as cdk from 'aws-cdk-lib';
import * as blueprints from '@aws-quickstart/eks-blueprints';
import { ExternalOperatorSecretAddon } from './externaloperatorsecretaddon';
const app = new cdk.App();
const addOns: Array<blueprints.ClusterAddOn> = [
new blueprints.addons.ExternalsSecretsAddOn(),
new blueprints.addons.FluxCDAddOn({
repositories:[
{
name: "<<YOUR_FLUX_APP_NAME>>",
namespace: "<<YOUR_FLUX_ADDON_NAMESPACE>>",
repository: {
repoUrl: '<<YOUR_PRIVATE_GIT_REPOSITORY>>',
targetRevision: "<<YOUR_TARGET_REVISION>>",
},
values: {
"region": "us-east-1"
},
kustomizations: [{kustomizationPath: "<<YOUR_FLUX_SYNC_PATH>>"}],
// This is the name of the kubernetes secret to be created by `ExternalSecret` shown in step 3.
secretRefName: "repository-creds"
}
],
}),
new ExternalOperatorSecretAddon(),
];
const blueprint = blueprints.EksBlueprint.builder()
.version("auto")
.addOns(addOns)
.build(app, 'my-stack-name');
- Below is the code snippet
externaloperatorsecretaddon.ts
which shows the mechanism to setupClusterSecretStore
andExternalSecret
to read AWS Secrets Managerbasic-access-auth
secret which is a GIT basic access authentication username and password to sync private repositories :
import 'source-map-support/register';
import * as blueprints from '@aws-quickstart/eks-blueprints';
import * as eks from "aws-cdk-lib/aws-eks";
import { Construct } from 'constructs';
import { dependable } from '@aws-quickstart/eks-blueprints/dist/utils';
export class ExternalOperatorSecretAddon implements blueprints.ClusterAddOn {
id?: string | undefined;
@dependable(blueprints.addons.ExternalsSecretsAddOn.name)
deploy(clusterInfo: blueprints.ClusterInfo): void | Promise<Construct> {
const cluster = clusterInfo.cluster;
const secretStore = new eks.KubernetesManifest(clusterInfo.cluster.stack, "ClusterSecretStore", {
cluster: cluster,
manifest: [
{
apiVersion: "external-secrets.io/v1beta1",
kind: "ClusterSecretStore",
metadata: {
name: "secret-manager-store",
namespace: "default"
},
spec: {
provider: {
aws: {
service: "SecretsManager",
region: clusterInfo.cluster.stack.region,
auth: {
jwt: {
serviceAccountRef: {
name: "external-secrets-sa",
namespace: "external-secrets",
},
},
},
},
},
},
},
],
});
const externalSecret = new eks.KubernetesManifest(clusterInfo.cluster.stack, "ExternalSecret", {
cluster: cluster,
manifest: [
{
apiVersion: "external-secrets.io/v1beta1",
kind: "ExternalSecret",
metadata: {
name: "git-admin-credentials",
namespace: "flux-system"
},
spec: {
secretStoreRef: {
name: "secret-manager-store",
kind: "ClusterSecretStore",
},
target: {
name: "repository-creds"
},
dataFrom: [
{
extract: {
key: "basic-access-auth"
},
},
],
},
},
],
});
externalSecret.node.addDependency(secretStore);
return Promise.resolve(secretStore);
}
}
- Upon execution of the above blueprint, the above
ExternalSecret
Kubernetes resource will take care of creating a Kubernetes Secret as shown below influx-system
namespace :
apiVersion: v1
kind: Secret
metadata:
name: repository-creds
namespace: flux-system
type: Opaque
data:
username: <<BASE64 ENCODED SECRET OF YOUR_GIT_USERNAME STORE in AWS SECRETS MANAGER>>
password: <<BASE64 ENCODED SECRET OF YOUR_GIT_TOKEN STORE in AWS SECRETS MANAGER>>
As pointed, if you are looking to use secretRef
to reference a secret for FluxCD addon to sync private Git repos, please make sure the referenced secret is already created in the namespace ahead of time in AWS Secrets Manager as shown above. You can use External Secrets Addon to learn more about external secrets operator which allows integration with third-party secret stores like AWS Secrets Manager, AWS Systems Manager Parameter Store and inject the values into the EKS cluster as Kubernetes Secrets.
Configuration Options¶
createNamespace
: (boolean) If you want CDK to create the namespace for you.values
: Arbitrary values to pass to the chart. Refer to the FluxCD Helm Chart documentation for additional details. It also supports all standard helm configuration options ( for Eg: https://github.com/aws-quickstart/cdk-eks-blueprints/blob/main/docs/addons/index.md#standard-helm-add-on-configuration-options).
Validation¶
To validate that fluxcd is installed properly in the cluster, check if the namespace is created and fluxcd pods are running.
Verify if the namespace is created correctly
kubectl get ns | grep "flux-system"
There should be list the flux-system namespace
flux-system Active 31m
Verify if the pods are running correctly in flux-system namespace
kubectl get pods -n flux-system
There should list 3 pods starting with name flux-system For Eg:
NAME READY STATUS RESTARTS AGE
helm-controller-65cc46469f-v4hnr 1/1 Running 0 6m13s
image-automation-controller-d8f7bfcb4-v4pz8 1/1 Running 0 6m13s
image-reflector-controller-68979dfd49-t4dpj 1/1 Running 0 6m13s
kustomize-controller-767677f7f5-7j26b 1/1 Running 0 6m13s
notification-controller-55d8c759f5-zqd6f 1/1 Running 0 6m13s
source-controller-58c66d55cd-4f6vh 1/1 Running 0 6m13s
Testing¶
The Flux CLI is available as a binary executable for all major platforms, the binaries can be downloaded form GitHub releases page.
Install Fluxcd client
curl -s https://fluxcd.io/install.sh | sudo bash
. <(flux completion bash)
Run the below command to check on the GitRepository
setup with Flux :
kubectl get gitrepository -A
NAME URL AGE READY STATUS
podinfo https://github.com/stefanprodan/podinfo 5s True stored artifact for revision 'master@sha1:132f4e719209eb10b9485302f8593fc0e680f4fc'
Run the below command to check on the Kustomization
setup with Flux :
❯ kubectl get kustomizations.kustomize.toolkit.fluxcd.io -A
NAMESPACE NAME AGE READY STATUS
flux-system podinfo 12m True Applied revision: master@sha1:073f1ec5aff930bd3411d33534e91cbe23302324