blob: 89242a82c9d0ad3a1297f77cf4249c687a1c7425 [file] [log] [blame]
Jakub Josef3947b062018-01-10 13:04:13 +01001/**
2 * Helper pipeline for AWS deployments from kqueen
3 *
4 * Expected parameters:
5 * STACK_NAME Infrastructure stack name
6 * STACK_TEMPLATE File with stack template
7 *
8 * STACK_TEMPLATE_URL URL to git repo with stack templates
9 * STACK_TEMPLATE_CREDENTIALS Credentials to the templates repo
10 * STACK_TEMPLATE_BRANCH Stack templates repo branch
11 * STACK_COMPUTE_COUNT Number of compute nodes to launch
12 *
13 * AWS_STACK_REGION CloudFormation AWS region
14 * AWS_API_CREDENTIALS AWS Access key ID with AWS secret access key
15 * AWS_SSH_KEY AWS key pair name (used for SSH access)
16 *
17 * SALT_MASTER_CREDENTIALS Credentials to the Salt API
18 * SALT_MASTER_URL URL of Salt master
19 */
20
21common = new com.mirantis.mk.Common()
22git = new com.mirantis.mk.Git()
23aws = new com.mirantis.mk.Aws()
24orchestrate = new com.mirantis.mk.Orchestrate()
25python = new com.mirantis.mk.Python()
26salt = new com.mirantis.mk.Salt()
27
28// Define global variables
29def venv
30def venvPepper
31def outputs = [:]
32
33def ipRegex = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
34def aws_env_vars
Jakub Joseffe0720e2018-01-11 17:43:53 +010035timeout(time: 12, unit: 'HOURS') {
36 node("python") {
37 try {
38 // Set build-specific variables
39 venv = "${env.WORKSPACE}/venv"
40 venvPepper = "${env.WORKSPACE}/venvPepper"
Jakub Josef3947b062018-01-10 13:04:13 +010041
Jakub Joseffe0720e2018-01-11 17:43:53 +010042 //
43 // Prepare machines
44 //
45 stage ('Create infrastructure') {
Jakub Josef3947b062018-01-10 13:04:13 +010046
Jakub Joseffe0720e2018-01-11 17:43:53 +010047 outputs.put('stack_type', "aws")
48 // setup environment
49 aws.setupVirtualEnv(venv)
50 // set aws_env_vars
51 aws_env_vars = aws.getEnvVars(AWS_API_CREDENTIALS, AWS_STACK_REGION)
52 // We just use STACK_NAME from param
53 currentBuild.description = STACK_NAME
54 outputs.put('stack_name', STACK_NAME)
Jakub Josef3947b062018-01-10 13:04:13 +010055
Jakub Joseffe0720e2018-01-11 17:43:53 +010056 // get templates
57 git.checkoutGitRepository('template', STACK_TEMPLATE_URL, STACK_TEMPLATE_BRANCH, STACK_TEMPLATE_CREDENTIALS)
Jakub Josef3947b062018-01-10 13:04:13 +010058
Jakub Joseffe0720e2018-01-11 17:43:53 +010059 // start stack
60 def stack_params = [
61 "ParameterKey=KeyName,ParameterValue=" + AWS_SSH_KEY,
62 "ParameterKey=CmpNodeCount,ParameterValue=" + STACK_COMPUTE_COUNT
63 ]
64 def template_file = 'cfn/' + STACK_TEMPLATE + '.yml'
65 aws.createStack(venv, aws_env_vars, template_file, STACK_NAME, stack_params)
Jakub Josef3947b062018-01-10 13:04:13 +010066
Jakub Joseffe0720e2018-01-11 17:43:53 +010067 // wait for stack to be ready
68 aws.waitForStatus(venv, aws_env_vars, STACK_NAME, 'CREATE_COMPLETE')
Jakub Josef3947b062018-01-10 13:04:13 +010069
Jakub Joseffe0720e2018-01-11 17:43:53 +010070 // get outputs
71 saltMasterHost = aws.getOutputs(venv, aws_env_vars, STACK_NAME, 'SaltMasterIP')
Jakub Josef3947b062018-01-10 13:04:13 +010072
Jakub Joseffe0720e2018-01-11 17:43:53 +010073 // check that saltMasterHost is valid
74 if (!saltMasterHost || !saltMasterHost.matches(ipRegex)) {
75 common.errorMsg("saltMasterHost is not a valid ip, value is: ${saltMasterHost}")
76 throw new Exception("saltMasterHost is not a valid ip")
77 }
78
79 currentBuild.description = "${STACK_NAME} ${saltMasterHost}"
80 SALT_MASTER_URL = "http://${saltMasterHost}:6969"
81
82 outputs.put('salt_api', SALT_MASTER_URL)
83
84 // Setup virtualenv for pepper
85 python.setupPepperVirtualenv(venvPepper, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Jakub Josef3947b062018-01-10 13:04:13 +010086 }
87
Jakub Joseffe0720e2018-01-11 17:43:53 +010088 stage('Install core infrastructure') {
89 def staticMgmtNetwork = false
90 if (common.validInputParam('STATIC_MGMT_NETWORK')) {
91 staticMgmtNetwork = STATIC_MGMT_NETWORK.toBoolean()
92 }
Jakub Josef3947b062018-01-10 13:04:13 +010093 orchestrate.installFoundationInfra(venvPepper, staticMgmtNetwork)
Jakub Josef3947b062018-01-10 13:04:13 +010094
Jakub Joseffe0720e2018-01-11 17:43:53 +010095 if (common.checkContains('STACK_INSTALL', 'kvm')) {
96 orchestrate.installInfraKvm(venvPepper)
97 orchestrate.installFoundationInfra(venvPepper, staticMgmtNetwork)
98 }
99
100 orchestrate.validateFoundationInfra(venvPepper)
101 }
102 stage('Install Kubernetes infra') {
Jakub Josef3947b062018-01-10 13:04:13 +0100103 // configure kubernetes_control_address - save loadbalancer
104 def awsOutputs = aws.getOutputs(venv, aws_env_vars, STACK_NAME)
105 common.prettyPrint(awsOutputs)
106 if (awsOutputs.containsKey('ControlLoadBalancer')) {
107 salt.runSaltProcessStep(venvPepper, 'I@salt:master', 'reclass.cluster_meta_set', ['kubernetes_control_address', awsOutputs['ControlLoadBalancer']], null, true)
108 outputs.put('kubernetes_apiserver', 'https://' + awsOutputs['ControlLoadBalancer'])
109 }
Jakub Joseffe0720e2018-01-11 17:43:53 +0100110
111 // ensure certificates are generated properly
112 salt.runSaltProcessStep(venvPepper, '*', 'saltutil.refresh_pillar', [], null, true)
113 salt.enforceState(venvPepper, '*', ['salt.minion.cert'], true)
114
115 orchestrate.installKubernetesInfra(venvPepper)
Jakub Josef3947b062018-01-10 13:04:13 +0100116 }
117
Jakub Joseffe0720e2018-01-11 17:43:53 +0100118 stage('Install Kubernetes control') {
119 orchestrate.installKubernetesControl(venvPepper)
Jakub Josef3947b062018-01-10 13:04:13 +0100120
Jakub Joseffe0720e2018-01-11 17:43:53 +0100121 // collect artifacts (kubeconfig)
122 writeFile(file: 'kubeconfig', text: salt.getFileContent(venvPepper, 'I@kubernetes:master and *01*', '/etc/kubernetes/admin-kube-config'))
123 archiveArtifacts(artifacts: 'kubeconfig')
124 }
Jakub Josef3947b062018-01-10 13:04:13 +0100125
Jakub Joseffe0720e2018-01-11 17:43:53 +0100126 stage('Install Kubernetes computes') {
127 if (common.validInputParam('STACK_COMPUTE_COUNT')) {
128 if (STACK_COMPUTE_COUNT > 0) {
129 // get stack info
130 def scaling_group = aws.getOutputs(venv, aws_env_vars, STACK_NAME, 'ComputesScalingGroup')
Jakub Josef3947b062018-01-10 13:04:13 +0100131
Jakub Joseffe0720e2018-01-11 17:43:53 +0100132 //update autoscaling group
133 aws.updateAutoscalingGroup(venv, aws_env_vars, scaling_group, ["--desired-capacity " + STACK_COMPUTE_COUNT])
Jakub Josef3947b062018-01-10 13:04:13 +0100134
Jakub Joseffe0720e2018-01-11 17:43:53 +0100135 // wait for computes to boot up
136 aws.waitForAutoscalingInstances(venv, aws_env_vars, scaling_group)
137 sleep(60)
138 }
Jakub Josef3947b062018-01-10 13:04:13 +0100139 }
Jakub Joseffe0720e2018-01-11 17:43:53 +0100140
141 orchestrate.installKubernetesCompute(venvPepper)
Jakub Josef3947b062018-01-10 13:04:13 +0100142 }
143
Jakub Joseffe0720e2018-01-11 17:43:53 +0100144 stage('Finalize') {
145 outputsPretty = common.prettify(outputs)
146 print(outputsPretty)
147 writeFile(file: 'outputs.json', text: outputsPretty)
148 archiveArtifacts(artifacts: 'outputs.json')
149 }
Jakub Josef3947b062018-01-10 13:04:13 +0100150
Jakub Joseffe0720e2018-01-11 17:43:53 +0100151 } catch (Throwable e) {
152 currentBuild.result = 'FAILURE'
153 throw e
154 } finally {
155 if (currentBuild.result == 'FAILURE') {
156 common.errorMsg("Deploy job FAILED and was not deleted. Please fix the problem and delete stack on you own.")
Jakub Josef3947b062018-01-10 13:04:13 +0100157
Jakub Joseffe0720e2018-01-11 17:43:53 +0100158 if (common.validInputParam('SALT_MASTER_URL')) {
159 common.errorMsg("Salt master URL: ${SALT_MASTER_URL}")
160 }
Jakub Josef3947b062018-01-10 13:04:13 +0100161 }
162 }
163 }
164}
165
166