Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flux update #794

Merged
merged 14 commits into from
Aug 4, 2023
54 changes: 51 additions & 3 deletions docs/addons/fluxcd.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,59 @@ const addOn = new blueprints.addons.FluxCDAddOn({
...

const blueprint = blueprints.EksBlueprint.builder()
.version("auto")
.addOns(addOn)
.build(app, 'my-stack-name');
.version("auto")
.addOns(addOn)
.build(app, 'my-stack-name');
```

## Workload Repositories

1. To add workload repositories as well as the bootstrap repository, please follow this example below

```typescript
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 addOn = new blueprints.addons.FluxCDAddOn({
Copy link
Collaborator

Choose a reason for hiding this comment

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

@zjaco13 was this example validated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes I validated it

bootstrapRepo: {
repoUrl: 'https://github.com/stefanprodan/podinfo',
name: "podinfo",
targetRevision: "master",
path: "./kustomize"
},
bootstrapValues: {
"region": "us-east-1"
},
workloadApplications: [
{
name: "nginx-grafanadashboard",
namespace: "grafana-operator",
repository: {
repoUrl: 'https://github.com/aws-observability/aws-observability-accelerator',
targetRevision: "main",
path: "./artifacts/grafana-operator-manifests/eks/nginx"
},
values: {
"GRAFANA_NGINX_DASH_URL" : nginxDashUrl,
},
}
],
});

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:
Expand Down
8 changes: 4 additions & 4 deletions lib/addons/fluxcd/gitrepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { setPath } from "../../utils";
*/
export class FluxGitRepository {

constructor(private readonly bootstrapRepo: spi.ApplicationRepository) {}
constructor(private readonly bootstrapRepo: spi.GitOpsApplicationDeployment) {}

public generate(namespace: string, fluxSyncInterval: string, fluxSecretRefName: string) {

Expand All @@ -20,9 +20,9 @@ export class FluxGitRepository {
},
spec: {
interval: fluxSyncInterval,
url: repository.repoUrl,
url: repository.repository?.repoUrl,
ref: {
branch: repository.targetRevision,
branch: repository.repository?.targetRevision,
},
}
};
Expand All @@ -31,4 +31,4 @@ export class FluxGitRepository {
}
return gitManifest;
}
}
}
86 changes: 55 additions & 31 deletions lib/addons/fluxcd/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ export interface FluxCDAddOnProps extends HelmAddOnUserProps {
* Flux Kustomization Timeout.
* Default `1m` */
fluxTimeout?: string;

/**
* List of Workload Applications to deploy
*/
workloadApplications?: spi.GitOpsApplicationDeployment[];
}

/**
Expand Down Expand Up @@ -122,56 +127,75 @@ export class FluxCDAddOn extends HelmAddOn {
chart.node.addDependency(namespace);
}

//Lets create a GitRepository resource as a source to Flux
if (this.options.bootstrapRepo?.repoUrl) {
const gitRepositoryConstruct = createGitRepository(clusterInfo, this.options);
gitRepositoryConstruct.node.addDependency(chart);

const kustomizationConstructs = createKustomizations(clusterInfo, this.options);
kustomizationConstructs.map(kustomizationConstruct => kustomizationConstruct.node.addDependency(gitRepositoryConstruct));
}
//Lets create a GitRepository resource as a source to Flux
if (this.options.bootstrapRepo?.repoUrl) {
const bootstrapRepo: spi.GitOpsApplicationDeployment = {
name: this.options.bootstrapRepo.name ?? "bootstrap-apps",
namespace: this.options.namespace!,
repository: this.options.bootstrapRepo,
values: this.options.bootstrapValues ?? {},
};
const gitRepositoryConstruct = createGitRepository(clusterInfo, bootstrapRepo, this.options);
gitRepositoryConstruct.node.addDependency(chart);
const kustomizationConstructs = createKustomizations(clusterInfo, bootstrapRepo, this.options);
kustomizationConstructs.map(kustomizationConstruct => kustomizationConstruct.node.addDependency(gitRepositoryConstruct));
}
if (this.options.workloadApplications) {
this.options.workloadApplications.forEach(app => {
const gitRepoConstruct = createGitRepository(clusterInfo, app, this.options);
gitRepoConstruct.node.addDependency(chart);
const kustomizationConstruct = createKustomization(clusterInfo, app, this.options);
kustomizationConstruct.node.addDependency(gitRepoConstruct);
});
}
return Promise.resolve(chart);
}
}

/**
* create GitRepository calls the FluxGitRepository().generate to create GitRepostory resource.
*/
function createGitRepository(clusterInfo: ClusterInfo, fluxcdAddonProps: FluxCDAddOnProps): KubernetesManifest {
if (fluxcdAddonProps.bootstrapRepo === undefined) {
throw new Error("Missing Git repository");
}

const manifest = new FluxGitRepository(fluxcdAddonProps.bootstrapRepo).generate(fluxcdAddonProps.namespace!, fluxcdAddonProps.fluxSyncInterval!, fluxcdAddonProps.fluxSecretRefName!);
let manifestName: string | undefined = fluxcdAddonProps.name + 'gitrepository';
const construct = clusterInfo.cluster.addManifest(manifestName!, manifest);
return construct;
function createGitRepository(clusterInfo: ClusterInfo, bootstrapRepo: spi.GitOpsApplicationDeployment, fluxcdAddonProps: FluxCDAddOnProps): KubernetesManifest {
const manifest = new FluxGitRepository(bootstrapRepo).generate(fluxcdAddonProps.namespace!, fluxcdAddonProps.fluxSyncInterval!, fluxcdAddonProps.fluxSecretRefName!);
let manifestName: string | undefined = fluxcdAddonProps.name + '-gitrepository-' + bootstrapRepo.name;
const construct = clusterInfo.cluster.addManifest(manifestName!, manifest);
return construct;
}

/**
* create Kustomizations calls the FluxKustomization().generate to create Kustomization resource.
*/
function createKustomization(clusterInfo: ClusterInfo, bootstrapRepo: spi.GitOpsApplicationDeployment, fluxcdAddonProps: FluxCDAddOnProps, fluxKustomizationPath?: string, manifestNameAddOns?: string, fluxKustomization?: FluxKustomization): KubernetesManifest {
fluxKustomization = fluxKustomization ?? new FluxKustomization(bootstrapRepo);
const manifest = fluxKustomization.generate(
bootstrapRepo.name,
fluxcdAddonProps.namespace!,
fluxcdAddonProps.fluxSyncInterval!,
bootstrapRepo.namespace ?? fluxcdAddonProps.fluxTargetNamespace!,
fluxcdAddonProps.fluxPrune!,
fluxcdAddonProps.fluxTimeout!,
bootstrapRepo.values,
fluxKustomizationPath ?? bootstrapRepo.repository?.path ?? ".",
);
let manifestName: string | undefined = fluxcdAddonProps.name + '-kustomization-' + bootstrapRepo.name + (manifestNameAddOns ? "-" + manifestNameAddOns : "");
const construct = clusterInfo.cluster.addManifest(manifestName!, manifest);
return construct;
}

/**
* create Kustomizations calls the FluxKustomization().generate multiple times to create Kustomization resources.
*/
function createKustomizations(clusterInfo: ClusterInfo, fluxcdAddonProps: FluxCDAddOnProps): KubernetesManifest[] {
let fluxKustomizationPaths = fluxcdAddonProps.bootstrapRepo?.path ? [fluxcdAddonProps.bootstrapRepo?.path] : ["."];
function createKustomizations(clusterInfo: ClusterInfo, bootstrapRepo: spi.GitOpsApplicationDeployment, fluxcdAddonProps: FluxCDAddOnProps): KubernetesManifest[] {
let fluxKustomizationPaths = bootstrapRepo.repository?.path ? [bootstrapRepo.repository?.path] : ["."];

if (fluxcdAddonProps.additionalFluxKustomizationPaths){
fluxKustomizationPaths = fluxKustomizationPaths.concat(fluxcdAddonProps.additionalFluxKustomizationPaths as string[]);
}

const constructs: KubernetesManifest[] = [];
const fluxKustomization = new FluxKustomization(fluxcdAddonProps.bootstrapRepo!);
const fluxKustomization = new FluxKustomization(bootstrapRepo);
fluxKustomizationPaths.map((fluxKustomizationPath, index) => {
const manifest =fluxKustomization.generate(
fluxcdAddonProps.bootstrapRepo!.name! + "-" + index,
fluxcdAddonProps.namespace!,
fluxcdAddonProps.fluxSyncInterval!,
fluxcdAddonProps.fluxTargetNamespace!,
fluxcdAddonProps.fluxPrune!,
fluxcdAddonProps.fluxTimeout!,
fluxcdAddonProps.bootstrapValues!,
fluxKustomizationPath);
let manifestName: string | undefined = fluxcdAddonProps.name + 'kustomization' + index;
constructs.push(clusterInfo.cluster.addManifest(manifestName!, manifest));
constructs.push(createKustomization(clusterInfo, bootstrapRepo, fluxcdAddonProps, fluxKustomizationPath, "" + index, fluxKustomization));
});

return constructs;
Expand Down
2 changes: 1 addition & 1 deletion lib/addons/fluxcd/kustomization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as spi from "../../spi";
*/
export class FluxKustomization {

constructor(private readonly bootstrapRepo: spi.ApplicationRepository) {}
constructor(private readonly bootstrapRepo: spi.GitOpsApplicationDeployment) {}

public generate(name: string, namespace: string, fluxSyncInterval: string, fluxTargetNamespace: string, fluxPrune: boolean, fluxTimeout: string, bootstrapValues: spi.Values, fluxKustomizationPath: string) {

Expand Down