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

Adding new pattern for Crossplane Argocd GitOps #173

Merged
merged 47 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
4eb131d
Adding new pattern for Crossplane Argocd GitOps
ajpaws May 15, 2024
81ac009
fixing review comments for cleanup
ajpaws Jun 3, 2024
a5d7aa3
adding error handling during stack creation
ajpaws Jun 10, 2024
26c4fd6
changing workloads path for argocd
ajpaws Jun 10, 2024
7a6a63a
cleanup and add arch diagram
ajpaws Jun 16, 2024
ffe0608
fixing review comments
ajpaws Jun 25, 2024
a7f97ae
passing variables values via gitops approach from argoCD
ajpaws Jun 25, 2024
60d940e
fixing doc errors
ajpaws Jun 25, 2024
ba54f88
add EKS Provider Addon and cleanup
ajpaws Jun 26, 2024
41331fa
fixing typos
ajpaws Jun 27, 2024
00b0337
fixing review comments
ajpaws Jul 22, 2024
fd069ae
automating iam role creation
ajpaws Aug 5, 2024
32eb8da
testing the stack
ajpaws Aug 5, 2024
ee94079
fixing pipeline errors
ajpaws Aug 7, 2024
32c457e
fixing deployment issues
ajpaws Aug 8, 2024
896e62f
fixing few deployment issues
ajpaws Aug 8, 2024
c3e1995
adding custom iam role creator resource
ajpaws Aug 14, 2024
80a8634
testing custom iam role creator resource
ajpaws Aug 14, 2024
f8f9442
fixing duplicate role creation
ajpaws Aug 14, 2024
26e0dca
testing custom iam role provider resource
ajpaws Aug 15, 2024
02aec06
fixing duplicate iam role creation
ajpaws Aug 16, 2024
89f43f4
clean up
ajpaws Aug 16, 2024
41bdaaf
cleanup
ajpaws Aug 17, 2024
d3a9bbf
Merge branch 'main' into main
shapirov103 Aug 26, 2024
2e5d709
creating dedicated IRSA role for EKS Provider
ajpaws Aug 27, 2024
8443c72
Merge branch 'main' of https://github.com/ajpaws/cdk-eks-blueprints-p…
ajpaws Aug 27, 2024
7bdb3db
creating dedicated iam role for eks provider pod
ajpaws Aug 28, 2024
f68efa8
automating secret creation
ajpaws Aug 28, 2024
152fc70
automating argocd secret creation
ajpaws Aug 28, 2024
8ae1ea7
cleanup and doc update
ajpaws Aug 28, 2024
0dcda7a
Merge pull request #1 from aws-samples/main
ajpaws Sep 4, 2024
58aaad5
update README
ajpaws Sep 4, 2024
311efbb
Merge branch 'main' of https://github.com/ajpaws/cdk-eks-blueprints-p…
ajpaws Sep 4, 2024
fd22534
fixing README Issues
ajpaws Sep 4, 2024
e58d132
update README
ajpaws Sep 10, 2024
1f3f4bb
Update multi-cluster-pipeline.ts
elamaran11 Sep 10, 2024
2902111
Update multi-cluster-pipeline.ts
elamaran11 Sep 10, 2024
55d345b
Update multi-cluster-pipeline.ts
elamaran11 Sep 10, 2024
d0d6615
removing secret store secret
ajpaws Sep 11, 2024
b18f5e7
fixing IRSA issues
ajpaws Sep 11, 2024
e796464
testing IRSA Issues
ajpaws Sep 11, 2024
c878437
testing IRSA roles
ajpaws Sep 11, 2024
ee3b16f
testing with new mgmt cluster
ajpaws Sep 12, 2024
1c6d95b
re-creating mgmt cluster
ajpaws Sep 12, 2024
146d656
fix number conversion issue
ajpaws Sep 16, 2024
6185b1a
Clean up and Update README
ajpaws Sep 17, 2024
ffaac77
update README
ajpaws Sep 17, 2024
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
45 changes: 45 additions & 0 deletions bin/aws-addon-clusters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import {K8S_VERSIONS_DEV, MultiClusterOptions} from "./multi-cluster-options";
import {CapacityType, KubernetesVersion} from "aws-cdk-lib/aws-eks";
import MultiClusterPipelineConstruct from "./multi-cluster-pipeline";
import * as blueprints from "@aws-quickstart/eks-blueprints";
import * as eks from "aws-cdk-lib/aws-eks";
import * as ec2 from "aws-cdk-lib/aws-ec2";

const app = new cdk.App();

const account = process.env.CDK_DEFAULT_ACCOUNT ?? "";
const region = process.env.CDK_DEFAULT_REGION ?? "us-east-1";
const minSize = parseInt(process.env.NODEGROUP_MIN ?? "1");
const maxSize = parseInt(process.env.NODEGROUP_MAX ?? "3");
const desiredSize = parseInt(process.env.NODEGROUP_DESIRED ?? "1");
const gitHubSecret = process.env.GITHUB_SECRET ?? "cdk_blueprints_github_secret";

const env : MultiClusterOptions = {
account,
region,
minSize,
maxSize,
desiredSize,
gitHubSecret,
nodeGroupCapacityType: CapacityType.ON_DEMAND,
k8sVersions: K8S_VERSIONS_DEV // K8S_VERSIONS_PROD for full deploy
}

Check failure on line 28 in bin/aws-addon-clusters.ts

View workflow job for this annotation

GitHub Actions / build (18)

Missing semicolon


const mngProps: blueprints.MngClusterProviderProps = {
version: KubernetesVersion.V1_28,
instanceTypes: [ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE2)],
amiType: eks.NodegroupAmiType.AL2_X86_64,
desiredSize: 2,
maxSize: 3,
};

console.info("Running CDK with id: addon-tester" );
console.info("Running CDK with: " + JSON.stringify(env));

new MultiClusterPipelineConstruct().buildAsync(app, "addon-tester", env , mngProps).catch(
(e) => console.log("Pipeline construct failed because of error ", e)
);

54 changes: 54 additions & 0 deletions bin/get-ready-for-test-issues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as AWS from "@aws-sdk/client-secrets-manager";
import { Octokit } from '@octokit/rest'

Check failure on line 2 in bin/get-ready-for-test-issues.ts

View workflow job for this annotation

GitHub Actions / build (18)

Missing semicolon

export const READY_FOR_TEST= "Ready for test";

/**
* Invoke with
* @param region process.env.CDK_DEFAULT_REGION
* @param secretName process.env.GITHUB_SECRET
* @param repo "jalawala"
* @param owner "aws-eks-addon-publication"
*/
export async function getReadyForTestAddons(region: string, secretName: string, repo: string, owner: string){
const issues = await getReadyForTestIssues(region, secretName, repo, owner) as Issue[];
// TODO do something with this addon
issues.forEach(issue => console.log(issue.number + ", " + issue.body));
}

async function getReadyForTestIssues(region: string, secretName: string, repo: string, owner: string){
const sm = new AWS.SecretsManager({region});

const accessToken = await getGitHubAccessToken(sm, secretName);
const octokit = new Octokit({ auth: accessToken });

const getIssuesRequest = {
headers: {
'X-GitHub-Api-Version': '2022-11-28'
},
owner,
repo,
labels: READY_FOR_TEST
};

const responsePromise = octokit.request("GET /repos/{owner}/{repo}/issues", getIssuesRequest);

Check failure on line 34 in bin/get-ready-for-test-issues.ts

View workflow job for this annotation

GitHub Actions / build (18)

Expected indentation of 4 spaces but found 3

return responsePromise
.then((response)=> response.data as Issue[])
.catch((error)=>{console.error(`Create issue error: ${error}`)})

Check failure on line 38 in bin/get-ready-for-test-issues.ts

View workflow job for this annotation

GitHub Actions / build (18)

Missing semicolon

Check failure on line 38 in bin/get-ready-for-test-issues.ts

View workflow job for this annotation

GitHub Actions / build (18)

Missing semicolon
}

type Issue = {
number: number;
body: string;
}

async function getGitHubAccessToken(sm : AWS.SecretsManager, secretName : string) {
const secret = await sm.getSecretValue({ SecretId: secretName });
const secretString = secret.SecretString;
if (typeof secretString === 'string') {
return secretString;
} else {
throw new Error('SecretString is not a string.');
}
}
23 changes: 23 additions & 0 deletions bin/multi-cluster-options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {CapacityType, KubernetesVersion} from "aws-cdk-lib/aws-eks";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as eks from "aws-cdk-lib/aws-eks";

export const K8S_VERSIONS_PROD : KubernetesVersion[] = [KubernetesVersion.V1_25, KubernetesVersion.V1_26,
KubernetesVersion.V1_27, KubernetesVersion.V1_28]; // KubernetesVersion.V1_29 // when the time comes
//export const K8S_VERSIONS_DEV : KubernetesVersion[] = [ KubernetesVersion.V1_26 ,KubernetesVersion.V1_27, KubernetesVersion.V1_28, KubernetesVersion.of("1.29")];

export const K8S_VERSIONS_DEV : KubernetesVersion[] = [ KubernetesVersion.of("1.29")];


export interface MultiClusterOptions {
readonly account: string;
readonly region: string;
minSize?: number;
maxSize?: number;
desiredSize?: number;
gitHubSecret?: string;
nodeGroupCapacityType: CapacityType;
instanceTypes?: ec2.InstanceType[];
amiType?: eks.NodegroupAmiType;
k8sVersions: KubernetesVersion[];
}
145 changes: 145 additions & 0 deletions bin/multi-cluster-pipeline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { Construct } from "constructs";
import * as blueprints from '@aws-quickstart/eks-blueprints';
import {K8S_VERSIONS_DEV, MultiClusterOptions} from "./multi-cluster-options";
import {NodegroupAmiType} from "aws-cdk-lib/aws-eks";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import ManagementClusterBuilder from "../lib/crossplane-argocd-gitops/management-cluster-builder";
import {ProviderMgmtRoleTeam} from "../lib/crossplane-argocd-gitops/custom-addons/mgmt-role-teams";
import {GenericClusterProvider, LookupRoleProvider} from "@aws-quickstart/eks-blueprints";
import {IRole} from "aws-cdk-lib/aws-iam";
import * as iam from 'aws-cdk-lib/aws-iam';
import {ManagedNodeGroup} from "@aws-quickstart/eks-blueprints/dist/cluster-providers/types";

export default class MultiClusterPipelineConstruct {
async buildAsync(scope: Construct, id: string, props: MultiClusterOptions, mngProps: blueprints.MngClusterProviderProps) {
const k8sVersions = props.k8sVersions ?? K8S_VERSIONS_DEV;
const region :string = props.region;
const account : string = props.account;

const gitProps = {
owner :'jalawala',
secretName : props.gitHubSecret ?? 'github-access-eks-addon',
repoName : 'aws-addon-clusters-main',
revision : 'main' // use this to target a certain branch for deployment
};


await this.prevalidateSecrets(gitProps.secretName, region);

const addOns: Array<blueprints.ClusterAddOn> = [
new blueprints.ExternalsSecretsAddOn({
namespace: "external-secrets",
values: { webhook: { port: 9443 } }
})
]

Check failure on line 34 in bin/multi-cluster-pipeline.ts

View workflow job for this annotation

GitHub Actions / build (18)

Missing semicolon

const clusterProps: blueprints.MngClusterProviderProps = {
minSize: props.minSize,
maxSize: props.maxSize,
desiredSize: props.desiredSize,
nodeGroupCapacityType: props.nodeGroupCapacityType,
}

Check failure on line 41 in bin/multi-cluster-pipeline.ts

View workflow job for this annotation

GitHub Actions / build (18)

Missing semicolon

const stages : blueprints.StackStage[] = [];
const vpcProvider= new blueprints.VpcProvider();

const baseBlueprint = blueprints.EksBlueprint.builder()
.resourceProvider(blueprints.GlobalResources.Vpc, vpcProvider)
.resourceProvider('eks-connector-role', new LookupRoleProvider('eks-connector-role'))
.account(account)
.addOns(...addOns)
.teams(new ProviderMgmtRoleTeam(account))
.useDefaultSecretEncryption(true);

const mgmtCluster = new ManagementClusterBuilder(account, region)
.create(scope, 'management-cluster', mngProps)
.account(account)
.region(region)
.resourceProvider(blueprints.GlobalResources.Vpc, vpcProvider);

const mgmtStage = [{id: `mgmt-cluster-stage` , stackBuilder: mgmtCluster}];

for(const k8sVersion of k8sVersions) {
baseBlueprint.version(k8sVersion);

const blueprintAMD = baseBlueprint
.clusterProvider(
new GenericClusterProvider( {
version: k8sVersion,
mastersRole: blueprints.getNamedResource('eks-connector-role') as IRole,
managedNodeGroups : [addManagedNodeGroup( 'amd-tst-ng',{...clusterProps,
amiType : NodegroupAmiType.AL2_X86_64,
instanceTypes: [ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE)]})]
})
);
stages.push({
id: `amd-` + k8sVersion.version.replace(".", "-"),
stackBuilder : blueprintAMD.clone(props.region).id(`amd-` + k8sVersion.version.replace(".", "-"))
});

const blueprintARM = baseBlueprint
.clusterProvider(
new GenericClusterProvider( {
version: k8sVersion,
mastersRole: blueprints.getNamedResource('eks-connector-role') as IRole,
managedNodeGroups : [addManagedNodeGroup('arm-tst-ng',{...clusterProps,
amiType : NodegroupAmiType.AL2_ARM_64,
instanceTypes: [ec2.InstanceType.of(ec2.InstanceClass.M7G, ec2.InstanceSize.XLARGE)]})]
})
);
stages.push({
id: `arm-` + k8sVersion.version.replace(".", "-"),
stackBuilder : blueprintARM.clone(props.region).id(`arm-` + k8sVersion.version.replace(".", "-"))
});
}

blueprints.CodePipelineStack.builder()
.name(id)
.owner(gitProps.owner)
.codeBuildPolicies(
([
new iam.PolicyStatement({
resources: ["*"],
actions: [
"codebuild:*",
"sts:AssumeRole",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecrets",
"secretsmanager:DescribeSecret",
"cloudformation:*"
]
})
])
)
.repository({
targetRevision : gitProps.revision,

Check failure on line 115 in bin/multi-cluster-pipeline.ts

View workflow job for this annotation

GitHub Actions / build (18)

Expected indentation of 16 spaces but found 20
credentialsSecretName: gitProps.secretName,

Check failure on line 116 in bin/multi-cluster-pipeline.ts

View workflow job for this annotation

GitHub Actions / build (18)

Expected indentation of 16 spaces but found 20
repoUrl: gitProps.repoName

Check failure on line 117 in bin/multi-cluster-pipeline.ts

View workflow job for this annotation

GitHub Actions / build (18)

Expected indentation of 16 spaces but found 20
}
)
.wave({ id: `mgmt-cluster-stage`, stages: mgmtStage })
.wave({ id: `${id}-wave`, stages })
.build(scope, id, { env: { account, region } });
}

async prevalidateSecrets(secretName: string, region: string) {
try {
await blueprints.utils.validateSecret(secretName, region);
}
catch(error) {
throw new Error(`${secretName} secret must be setup in AWS Secrets Manager in ${region} for the GitHub pipeline.
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/GitHub-create-personal-token-CLI.html`);
}
}
}

function addManagedNodeGroup(id: string, clusterProps: blueprints.MngClusterProviderProps): ManagedNodeGroup {
return {
id,
minSize: clusterProps.minSize,
maxSize: clusterProps.maxSize,
amiType: clusterProps.amiType,
instanceTypes: clusterProps.instanceTypes,
desiredSize: clusterProps.desiredSize
};
}
Loading
Loading