Skip to content

Commit b5657ab

Browse files
authored
Added logic to deploy default jenkins agent (#176)
* Changed cpu and memory metric stat to avg Signed-off-by: Rishabh Singh <sngri@amazon.com> * Added logic to default on dummy jenkins agent Signed-off-by: Rishabh Singh <sngri@amazon.com>
1 parent d9dbf38 commit b5657ab

File tree

4 files changed

+109
-23
lines changed

4 files changed

+109
-23
lines changed

README.md

+26-13
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- [Add environment variable](#add-environment-variables)
1414
- [Assume role](#cross-account-assume-role)
1515
- [Mac agents](#mac-agents)
16+
- [Use Production Agents](#use-production-agents)
1617
- [Troubleshooting](#troubleshooting)
1718
- [Main Node](#main-node)
1819
- [Useful commands](#useful-commands)
@@ -76,18 +77,19 @@ $aws secretsmanager put-secret-value \
7677

7778
### Executing Optional Tasks
7879
#### Construct Props
79-
| Name | Type | Description |
80-
| ------------- |:-------------| :-----|
81-
| [useSsl](#ssl-configuration) | boolean | Should the Jenkins use https |
82-
| [runWithOidc](#setup-openid-connect-oidc-via-federate) | boolean | Should an OIDC provider be installed on Jenkins |
83-
| [ignoreResourcesFailures]() | boolean | Additional verification during deployment and resource startup |
84-
| [adminUsers](#setup-openid-connect-oidc-via-federate) | string[] | List of users with admin access during initial deployment |
85-
| [additionalCommands](#runnning-additional-commands) | string | Additional logic that needs to be run on Master Node. The value has to be path to a file |
86-
| [dataRetention](#data-retention) | boolean | Do you want to retain jenkins jobs and build history |
87-
| [agentAssumeRole](#assume-role) | string | IAM role ARN to be assumed by jenkins agent nodes |
88-
| [envVarsFilePath](#add-environment-variables) | string | Path to file containing env variables in the form of key value pairs |
89-
| [macAgent](#mac-agents) | boolean | Add mac agents to jenkins |
90-
| [restrictServerAccessTo](#restricting-server-access) | Ipeer | Restrict jenkins server access |
80+
| Name | Type | Description |
81+
|--------------------------------------------------------|:---------|:-----------------------------------------------------------------------------------------|
82+
| [useSsl](#ssl-configuration) | boolean | Should the Jenkins use https |
83+
| [runWithOidc](#setup-openid-connect-oidc-via-federate) | boolean | Should an OIDC provider be installed on Jenkins |
84+
| [ignoreResourcesFailures]() | boolean | Additional verification during deployment and resource startup |
85+
| [adminUsers](#setup-openid-connect-oidc-via-federate) | string[] | List of users with admin access during initial deployment |
86+
| [additionalCommands](#runnning-additional-commands) | string | Additional logic that needs to be run on Master Node. The value has to be path to a file |
87+
| [dataRetention](#data-retention) | boolean | Do you want to retain jenkins jobs and build history |
88+
| [agentAssumeRole](#assume-role) | string | IAM role ARN to be assumed by jenkins agent nodes |
89+
| [envVarsFilePath](#add-environment-variables) | string | Path to file containing env variables in the form of key value pairs |
90+
| [macAgent](#mac-agents) | boolean | Add mac agents to jenkins |
91+
| [restrictServerAccessTo](#restricting-server-access) | Ipeer | Restrict jenkins server access |
92+
| [useProdAgents](#use-production-agents) | boolean | should jenkins server use production agents |
9193
#### SSL Configuration
9294
1. Locate the secret manager arns in the ci-config-stack outputs
9395
1. Update the secret value ([see docs](https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/put-secret-value.html)) for the `certContentsSecret` with the certificate contents
@@ -201,6 +203,17 @@ Usage:
201203
npm run cdk deploy OpenSearch-CI-Dev -- -c useSsl=false -c runWithOidc=false -c additionalCommands='./example.txt'
202204
```
203205
206+
#### Use Production Agents
207+
Please note that if you have decided to use the provided production jenkins agents then please make sure that you are
208+
deploying the stack in US-EAST-1 region as the AMIs used are only publicly available in US-EAST-1 region.
209+
If you want to deploy the stack in another region then please make sure you copy the public AMIs used
210+
from us-east-1 region to your region of choice and update the new ami-id in agent-nodes.ts file accordingly.
211+
212+
If you do not copy the AMI in required region and update the code then the desired jenkins agents will not spin up.
213+
214+
If you do not specify this flag or use `false` then jenkins server will spin up two ec2 agents with minimal config, AL2 AMD64 and ARM64,
215+
they will be using the latest ami available.
216+
204217
### Troubleshooting
205218
#### Main Node
206219
Useful links
@@ -247,4 +260,4 @@ This project is licensed under the [Apache v2.0 License](LICENSE.txt).
247260
248261
## Copyright
249262
250-
Copyright OpenSearch Contributors. See [NOTICE](NOTICE.txt) for details.
263+
Copyright OpenSearch Contributors. See [NOTICE](NOTICE.txt) for details.

lib/ci-stack.ts

+28-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '@aws-cdk/core';
1717
import { ListenerCertificate } from '@aws-cdk/aws-elasticloadbalancingv2';
1818
import { Bucket } from '@aws-cdk/aws-s3';
19+
import { disconnect } from 'cluster';
1920
import { CIConfigStack } from './ci-config-stack';
2021
import { JenkinsMainNode } from './compute/jenkins-main-node';
2122
import { JenkinsMonitoring } from './monitoring/ci-alarms';
@@ -47,11 +48,15 @@ export interface CIStackProps extends StackProps {
4748
readonly macAgent?: boolean;
4849
/** Restrict jenkins access to */
4950
readonly restrictServerAccessTo? : IPeer;
51+
/** Use Production Agents */
52+
readonly useProdAgents?: boolean;
5053
}
5154

5255
export class CIStack extends Stack {
5356
public readonly monitoring: JenkinsMonitoring;
5457

58+
public readonly agentNodes: AgentNodeProps[];
59+
5560
constructor(scope: Construct, id: string, props: CIStackProps) {
5661
super(scope, id, props);
5762

@@ -80,6 +85,11 @@ export class CIStack extends Stack {
8085
throw new Error('runWithOidc parameter is required to be set as - true or false');
8186
}
8287

88+
let useProdAgents = `${props?.useProdAgents ?? this.node.tryGetContext('useProdAgents')}`;
89+
if (useProdAgents.toString() === 'undefined') {
90+
useProdAgents = 'false';
91+
}
92+
8393
const runWithOidc = runWithOidcParameter === 'true';
8494

8595
const additionalCommandsContext = `${props?.additionalCommands ?? this.node.tryGetContext('additionalCommands')}`;
@@ -106,10 +116,23 @@ export class CIStack extends Stack {
106116
const certificateArn = Secret.fromSecretCompleteArn(this, 'certificateArn', importedArnSecretBucketValue.toString());
107117
const importedReloadPasswordSecretsArn = Fn.importValue(`${CIConfigStack.CASC_RELOAD_TOKEN_SECRET_EXPORT_VALUE}`);
108118
const listenerCertificate = ListenerCertificate.fromArn(certificateArn.secretValue.toString());
109-
const agentNode = new AgentNodes();
110-
const agentNodes: AgentNodeProps[] = [agentNode.AL2_X64, agentNode.AL2_X64_DOCKER_HOST, agentNode.AL2_X64_DOCKER_HOST_PERF_TEST,
111-
agentNode.AL2_ARM64, agentNode.AL2_ARM64_DOCKER_HOST, agentNode.UBUNTU2004_X64, agentNode.UBUNTU2004_X64_DOCKER_BUILDER,
112-
agentNode.MACOS12_X64_MULTI_HOST, agentNode.WINDOWS2019_X64];
119+
const agentNode = new AgentNodes(this);
120+
121+
if (useProdAgents.toString() === 'true') {
122+
// eslint-disable-next-line no-console
123+
console.warn('Please note that if you have decided to use the provided production jenkins agents then '
124+
+ 'please make sure that you are deploying the stack in US-EAST-1 region as the AMIs used are only publicly '
125+
+ 'available in US-EAST-1 region. '
126+
+ 'If you want to deploy the stack in another region then please make sure you copy the public AMIs used '
127+
+ 'from us-east-1 region to your region of choice and update the ami-id in agent-nodes.ts file accordingly. '
128+
+ 'If you do not copy the AMI in required region and update the code then the jenkins agents will not spin up.');
129+
130+
this.agentNodes = [agentNode.AL2_X64, agentNode.AL2_X64_DOCKER_HOST, agentNode.AL2_X64_DOCKER_HOST_PERF_TEST,
131+
agentNode.AL2_ARM64, agentNode.AL2_ARM64_DOCKER_HOST, agentNode.UBUNTU2004_X64, agentNode.UBUNTU2004_X64_DOCKER_BUILDER,
132+
agentNode.MACOS12_X64_MULTI_HOST, agentNode.WINDOWS2019_X64];
133+
} else {
134+
this.agentNodes = [agentNode.AL2_X64_DEFAULT_AGENT, agentNode.AL2_ARM64_DEFAULT_AGENT];
135+
}
113136

114137
const mainJenkinsNode = new JenkinsMainNode(this, {
115138
vpc,
@@ -129,7 +152,7 @@ export class CIStack extends Stack {
129152
adminUsers: props?.adminUsers,
130153
agentNodeSecurityGroup: securityGroups.agentNodeSG.securityGroupId,
131154
subnetId: vpc.publicSubnets[0].subnetId,
132-
}, agentNodes, agentAssumeRoleContext.toString(), macAgentParameter.toString());
155+
}, this.agentNodes, agentAssumeRoleContext.toString(), macAgentParameter.toString());
133156

134157
const externalLoadBalancer = new JenkinsExternalLoadBalancer(this, {
135158
vpc,

lib/compute/agent-node-config.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ export interface AgentNodeProps {
2525
remoteUser: string;
2626
maxTotalUses: number;
2727
numExecutors: number;
28-
initScript: string
28+
initScript: string,
29+
remoteFs: string
2930
}
3031
export interface AgentNodeNetworkProps {
3132
readonly agentNodeSecurityGroup: string;
@@ -179,7 +180,7 @@ export class AgentNodeConfig {
179180
monitoring: true,
180181
numExecutors: config.numExecutors,
181182
remoteAdmin: config.remoteUser,
182-
remoteFS: '/var/jenkins',
183+
remoteFS: config.remoteFs,
183184
securityGroups: props.agentNodeSecurityGroup,
184185
stopOnTerminate: false,
185186
subnetId: props.subnetId,
@@ -225,7 +226,7 @@ export class AgentNodeConfig {
225226
monitoring: true,
226227
numExecutors: config.numExecutors,
227228
remoteAdmin: config.remoteUser,
228-
remoteFS: '/var/jenkins',
229+
remoteFS: config.remoteFs,
229230
securityGroups: props.agentNodeSecurityGroup,
230231
stopOnTerminate: false,
231232
subnetId: props.subnetId,
@@ -276,7 +277,7 @@ export class AgentNodeConfig {
276277
monitoring: true,
277278
numExecutors: config.numExecutors,
278279
remoteAdmin: config.remoteUser,
279-
remoteFS: `C:\\Users\\${config.remoteUser}\\jenkins`,
280+
remoteFS: config.remoteFs,
280281
securityGroups: props.agentNodeSecurityGroup,
281282
stopOnTerminate: false,
282283
subnetId: props.subnetId,

lib/compute/agent-nodes.ts

+50-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* compatible open source license.
77
*/
88

9+
import { AmazonLinuxCpuType, AmazonLinuxGeneration, MachineImage } from '@aws-cdk/aws-ec2';
10+
import { Stack } from '@aws-cdk/core';
911
import { AgentNodeProps } from './agent-node-config';
1012

1113
export class AgentNodes {
@@ -28,7 +30,11 @@ export class AgentNodes {
2830

2931
readonly WINDOWS2019_X64: AgentNodeProps;
3032

31-
constructor() {
33+
readonly AL2_X64_DEFAULT_AGENT: AgentNodeProps;
34+
35+
readonly AL2_ARM64_DEFAULT_AGENT: AgentNodeProps;
36+
37+
constructor(stack: Stack) {
3238
this.AL2_X64 = {
3339
agentType: 'unix',
3440
workerLabelString: 'Jenkins-Agent-AL2-X64-C54xlarge-Single-Host',
@@ -40,6 +46,7 @@ export class AgentNodes {
4046
initScript: 'sudo yum clean all && sudo rm -rf /var/cache/yum /var/lib/yum/history && sudo yum repolist &&'
4147
+ ' sudo yum update --skip-broken --exclude=openssh* --exclude=docker* -y && sudo yum install -y ntp &&'
4248
+ ' sudo systemctl restart ntpd && sudo systemctl enable ntpd',
49+
remoteFs: '/var/jenkins',
4350
};
4451
this.AL2_X64_DOCKER_HOST = {
4552
agentType: 'unix',
@@ -52,6 +59,7 @@ export class AgentNodes {
5259
initScript: 'sudo yum clean all && sudo rm -rf /var/cache/yum /var/lib/yum/history && sudo yum repolist &&'
5360
+ ' sudo yum update --skip-broken --exclude=openssh* --exclude=docker* -y && sudo yum install -y ntp &&'
5461
+ ' sudo systemctl restart ntpd && sudo systemctl enable ntpd',
62+
remoteFs: '/var/jenkins',
5563
};
5664
this.AL2_X64_DOCKER_HOST_PERF_TEST = {
5765
agentType: 'unix',
@@ -64,6 +72,7 @@ export class AgentNodes {
6472
initScript: 'sudo yum clean all && sudo rm -rf /var/cache/yum /var/lib/yum/history && sudo yum repolist &&'
6573
+ ' sudo yum update --skip-broken --exclude=openssh* --exclude=docker* -y && sudo yum install -y ntp &&'
6674
+ ' sudo systemctl restart ntpd && sudo systemctl enable ntpd',
75+
remoteFs: '/var/jenkins',
6776
};
6877
this.AL2_ARM64 = {
6978
agentType: 'unix',
@@ -76,6 +85,7 @@ export class AgentNodes {
7685
initScript: 'sudo yum clean all && sudo rm -rf /var/cache/yum /var/lib/yum/history && sudo yum repolist &&'
7786
+ ' sudo yum update --skip-broken --exclude=openssh* --exclude=docker* -y && sudo yum install -y ntp &&'
7887
+ ' sudo systemctl restart ntpd && sudo systemctl enable ntpd',
88+
remoteFs: '/var/jenkins',
7989
};
8090
this.AL2_ARM64_DOCKER_HOST = {
8191
agentType: 'unix',
@@ -88,6 +98,7 @@ export class AgentNodes {
8898
initScript: 'sudo yum clean all && sudo rm -rf /var/cache/yum /var/lib/yum/history && sudo yum repolist &&'
8999
+ ' sudo yum update --skip-broken --exclude=openssh* --exclude=docker* -y && sudo yum install -y ntp &&'
90100
+ ' sudo systemctl restart ntpd && sudo systemctl enable ntpd',
101+
remoteFs: '/var/jenkins',
91102
};
92103
this.UBUNTU2004_X64 = {
93104
agentType: 'unix',
@@ -101,6 +112,7 @@ export class AgentNodes {
101112
+ ' sudo apt-get update && (sudo killall -9 apt-get apt 2>&1 || echo) &&'
102113
+ ' sudo apt-get upgrade -y && sudo apt-get install -y ntp docker-compose &&'
103114
+ ' sudo systemctl restart ntp && sudo systemctl enable ntp',
115+
remoteFs: '/var/jenkins',
104116
};
105117
this.UBUNTU2004_X64_DOCKER_BUILDER = {
106118
agentType: 'unix',
@@ -114,6 +126,7 @@ export class AgentNodes {
114126
+ ' sudo apt-get update && (sudo killall -9 apt-get apt 2>&1 || echo) &&'
115127
+ ' sudo apt-get upgrade -y && sudo apt-get install -y ntp docker-compose &&'
116128
+ ' sudo systemctl restart ntp && sudo systemctl enable ntp',
129+
remoteFs: '/var/jenkins',
117130
};
118131
this.MACOS12_X64_MULTI_HOST = {
119132
agentType: 'mac',
@@ -124,6 +137,7 @@ export class AgentNodes {
124137
numExecutors: 6,
125138
amiId: 'ami-022cee9eedb91288a',
126139
initScript: 'echo',
140+
remoteFs: '/var/jenkins',
127141
};
128142
this.WINDOWS2019_X64 = {
129143
agentType: 'windows',
@@ -134,6 +148,41 @@ export class AgentNodes {
134148
numExecutors: 1,
135149
amiId: 'ami-07591ca4ef792c2d4',
136150
initScript: 'echo',
151+
remoteFs: 'C:\\Users\\Administrator\\jenkins',
152+
};
153+
154+
this.AL2_X64_DEFAULT_AGENT = {
155+
agentType: 'unix',
156+
workerLabelString: 'Jenkins-Default-Agent-X64-C5xlarge-Single-Host',
157+
instanceType: 'C54xlarge',
158+
remoteUser: 'ec2-user',
159+
maxTotalUses: -1,
160+
numExecutors: 1,
161+
amiId: MachineImage.latestAmazonLinux({
162+
generation: AmazonLinuxGeneration.AMAZON_LINUX_2,
163+
cpuType: AmazonLinuxCpuType.X86_64,
164+
}).getImage(stack).imageId.toString(),
165+
initScript: 'sudo yum install -y java-1.8.0-openjdk cmake python3 python3-pip && '
166+
+ 'sudo yum groupinstall -y \'Development Tools\' && sudo ln -sfn `which pip3` /usr/bin/pip && '
167+
+ 'pip3 install pipenv && sudo ln -s ~/.local/bin/pipenv /usr/local/bin',
168+
remoteFs: '/home/ec2-user',
169+
};
170+
171+
this.AL2_ARM64_DEFAULT_AGENT = {
172+
agentType: 'unix',
173+
workerLabelString: 'Jenkins-Default-Agent-ARM64-C5xlarge-Single-Host',
174+
instanceType: 'C6g4xlarge',
175+
remoteUser: 'ec2-user',
176+
maxTotalUses: -1,
177+
numExecutors: 1,
178+
amiId: MachineImage.latestAmazonLinux({
179+
generation: AmazonLinuxGeneration.AMAZON_LINUX_2,
180+
cpuType: AmazonLinuxCpuType.ARM_64,
181+
}).getImage(stack).imageId.toString(),
182+
initScript: 'sudo yum install -y java-1.8.0-openjdk cmake python3 python3-pip && '
183+
+ 'sudo yum groupinstall -y \'Development Tools\' && sudo ln -sfn `which pip3` /usr/bin/pip && '
184+
+ 'pip3 install pipenv && sudo ln -s ~/.local/bin/pipenv /usr/local/bin',
185+
remoteFs: '/home/ec2-user',
137186
};
138187
}
139188
}

0 commit comments

Comments
 (0)