blob: 8fd92bfa0a373d77b698c164ef470120a9284223 [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
vnaumov56746cc2018-04-25 15:09:37 +040019 *
20 * optional parameters for overwriting soft params
21 * SALT_OVERRIDES YAML with overrides for Salt deployment
Jakub Josef3947b062018-01-10 13:04:13 +010022 */
23
24common = new com.mirantis.mk.Common()
25git = new com.mirantis.mk.Git()
26aws = new com.mirantis.mk.Aws()
27orchestrate = new com.mirantis.mk.Orchestrate()
28python = new com.mirantis.mk.Python()
29salt = new com.mirantis.mk.Salt()
30
vnaumov56746cc2018-04-25 15:09:37 +040031
Jakub Josef3947b062018-01-10 13:04:13 +010032// Define global variables
33def venv
34def venvPepper
35def outputs = [:]
36
37def ipRegex = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"
38def aws_env_vars
Jakub Joseffe0720e2018-01-11 17:43:53 +010039timeout(time: 12, unit: 'HOURS') {
40 node("python") {
41 try {
42 // Set build-specific variables
43 venv = "${env.WORKSPACE}/venv"
44 venvPepper = "${env.WORKSPACE}/venvPepper"
Jakub Josef3947b062018-01-10 13:04:13 +010045
Jakub Joseffe0720e2018-01-11 17:43:53 +010046 //
47 // Prepare machines
48 //
49 stage ('Create infrastructure') {
Jakub Josef3947b062018-01-10 13:04:13 +010050
Jakub Joseffe0720e2018-01-11 17:43:53 +010051 outputs.put('stack_type', "aws")
52 // setup environment
53 aws.setupVirtualEnv(venv)
54 // set aws_env_vars
55 aws_env_vars = aws.getEnvVars(AWS_API_CREDENTIALS, AWS_STACK_REGION)
56 // We just use STACK_NAME from param
57 currentBuild.description = STACK_NAME
58 outputs.put('stack_name', STACK_NAME)
Jakub Josef3947b062018-01-10 13:04:13 +010059
Jakub Joseffe0720e2018-01-11 17:43:53 +010060 // get templates
61 git.checkoutGitRepository('template', STACK_TEMPLATE_URL, STACK_TEMPLATE_BRANCH, STACK_TEMPLATE_CREDENTIALS)
Jakub Josef3947b062018-01-10 13:04:13 +010062
Jakub Joseffe0720e2018-01-11 17:43:53 +010063 // start stack
64 def stack_params = [
65 "ParameterKey=KeyName,ParameterValue=" + AWS_SSH_KEY,
66 "ParameterKey=CmpNodeCount,ParameterValue=" + STACK_COMPUTE_COUNT
67 ]
68 def template_file = 'cfn/' + STACK_TEMPLATE + '.yml'
69 aws.createStack(venv, aws_env_vars, template_file, STACK_NAME, stack_params)
Jakub Josef3947b062018-01-10 13:04:13 +010070
Jakub Joseffe0720e2018-01-11 17:43:53 +010071 // wait for stack to be ready
vnaumov59578f72018-05-14 15:21:48 +040072 aws.waitForStatus(venv, aws_env_vars, STACK_NAME, 'CREATE_COMPLETE', ['ROLLBACK_COMPLETE'], 2400, 30)
Jakub Josef3947b062018-01-10 13:04:13 +010073
Jakub Joseffe0720e2018-01-11 17:43:53 +010074 // get outputs
75 saltMasterHost = aws.getOutputs(venv, aws_env_vars, STACK_NAME, 'SaltMasterIP')
Jakub Josef3947b062018-01-10 13:04:13 +010076
Jakub Joseffe0720e2018-01-11 17:43:53 +010077 // check that saltMasterHost is valid
78 if (!saltMasterHost || !saltMasterHost.matches(ipRegex)) {
79 common.errorMsg("saltMasterHost is not a valid ip, value is: ${saltMasterHost}")
80 throw new Exception("saltMasterHost is not a valid ip")
81 }
82
83 currentBuild.description = "${STACK_NAME} ${saltMasterHost}"
84 SALT_MASTER_URL = "http://${saltMasterHost}:6969"
85
86 outputs.put('salt_api', SALT_MASTER_URL)
87
88 // Setup virtualenv for pepper
89 python.setupPepperVirtualenv(venvPepper, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
Jakub Josef3947b062018-01-10 13:04:13 +010090 }
91
vnaumov56746cc2018-04-25 15:09:37 +040092 // Set up override params
93 if (common.validInputParam('SALT_OVERRIDES')) {
94 stage('Set Salt overrides') {
95 salt.setSaltOverrides(venvPepper, SALT_OVERRIDES)
96 }
97 }
98
99 //
100 // Install
101 //
102
Jakub Joseffe0720e2018-01-11 17:43:53 +0100103 stage('Install core infrastructure') {
104 def staticMgmtNetwork = false
105 if (common.validInputParam('STATIC_MGMT_NETWORK')) {
106 staticMgmtNetwork = STATIC_MGMT_NETWORK.toBoolean()
107 }
Jakub Josef3947b062018-01-10 13:04:13 +0100108 orchestrate.installFoundationInfra(venvPepper, staticMgmtNetwork)
Jakub Josef3947b062018-01-10 13:04:13 +0100109
Jakub Joseffe0720e2018-01-11 17:43:53 +0100110 if (common.checkContains('STACK_INSTALL', 'kvm')) {
111 orchestrate.installInfraKvm(venvPepper)
112 orchestrate.installFoundationInfra(venvPepper, staticMgmtNetwork)
113 }
114
115 orchestrate.validateFoundationInfra(venvPepper)
116 }
117 stage('Install Kubernetes infra') {
Jakub Josef3947b062018-01-10 13:04:13 +0100118 // configure kubernetes_control_address - save loadbalancer
119 def awsOutputs = aws.getOutputs(venv, aws_env_vars, STACK_NAME)
120 common.prettyPrint(awsOutputs)
121 if (awsOutputs.containsKey('ControlLoadBalancer')) {
122 salt.runSaltProcessStep(venvPepper, 'I@salt:master', 'reclass.cluster_meta_set', ['kubernetes_control_address', awsOutputs['ControlLoadBalancer']], null, true)
123 outputs.put('kubernetes_apiserver', 'https://' + awsOutputs['ControlLoadBalancer'])
124 }
Jakub Joseffe0720e2018-01-11 17:43:53 +0100125
126 // ensure certificates are generated properly
Andrey Shestakovf23ed002018-08-21 12:09:51 +0300127 salt.runSaltProcessStep(venvPepper, 'I@kubernetes:*', 'saltutil.refresh_pillar', [], null, true)
128 salt.enforceState(venvPepper, 'I@kubernetes:*', ['salt.minion.cert'], true)
Jakub Joseffe0720e2018-01-11 17:43:53 +0100129
130 orchestrate.installKubernetesInfra(venvPepper)
Jakub Josef3947b062018-01-10 13:04:13 +0100131 }
132
Jakub Joseffe0720e2018-01-11 17:43:53 +0100133 stage('Install Kubernetes control') {
134 orchestrate.installKubernetesControl(venvPepper)
Jakub Josef3947b062018-01-10 13:04:13 +0100135
Jakub Joseffe0720e2018-01-11 17:43:53 +0100136 // collect artifacts (kubeconfig)
137 writeFile(file: 'kubeconfig', text: salt.getFileContent(venvPepper, 'I@kubernetes:master and *01*', '/etc/kubernetes/admin-kube-config'))
138 archiveArtifacts(artifacts: 'kubeconfig')
139 }
Jakub Josef3947b062018-01-10 13:04:13 +0100140
Jakub Joseffe0720e2018-01-11 17:43:53 +0100141 stage('Install Kubernetes computes') {
142 if (common.validInputParam('STACK_COMPUTE_COUNT')) {
143 if (STACK_COMPUTE_COUNT > 0) {
144 // get stack info
145 def scaling_group = aws.getOutputs(venv, aws_env_vars, STACK_NAME, 'ComputesScalingGroup')
Jakub Josef3947b062018-01-10 13:04:13 +0100146
Jakub Joseffe0720e2018-01-11 17:43:53 +0100147 //update autoscaling group
148 aws.updateAutoscalingGroup(venv, aws_env_vars, scaling_group, ["--desired-capacity " + STACK_COMPUTE_COUNT])
Jakub Josef3947b062018-01-10 13:04:13 +0100149
Jakub Joseffe0720e2018-01-11 17:43:53 +0100150 // wait for computes to boot up
151 aws.waitForAutoscalingInstances(venv, aws_env_vars, scaling_group)
152 sleep(60)
153 }
Jakub Josef3947b062018-01-10 13:04:13 +0100154 }
Jakub Joseffe0720e2018-01-11 17:43:53 +0100155
156 orchestrate.installKubernetesCompute(venvPepper)
Jakub Josef3947b062018-01-10 13:04:13 +0100157 }
158
Jakub Joseffe0720e2018-01-11 17:43:53 +0100159 stage('Finalize') {
160 outputsPretty = common.prettify(outputs)
161 print(outputsPretty)
162 writeFile(file: 'outputs.json', text: outputsPretty)
163 archiveArtifacts(artifacts: 'outputs.json')
164 }
Jakub Josef3947b062018-01-10 13:04:13 +0100165
Jakub Joseffe0720e2018-01-11 17:43:53 +0100166 } catch (Throwable e) {
167 currentBuild.result = 'FAILURE'
168 throw e
169 } finally {
170 if (currentBuild.result == 'FAILURE') {
171 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 +0100172
Jakub Joseffe0720e2018-01-11 17:43:53 +0100173 if (common.validInputParam('SALT_MASTER_URL')) {
174 common.errorMsg("Salt master URL: ${SALT_MASTER_URL}")
175 }
Jakub Josef3947b062018-01-10 13:04:13 +0100176 }
177 }
178 }
179}
180
181