This repository has been archived by the owner on Jan 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
puppetmaster.sh
316 lines (272 loc) · 10.1 KB
/
puppetmaster.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
#!/bin/bash
### START OF CONF ###
## You probably want to change these ##
DEFAULT_DOMAIN=
GITREPO=
PUPPET_VER="puppet6"
PUPPETSERVERCLASS=
## You _may_ want to change these ##
PP_ENVIRONMENT="test"
PP_SERVICE="puppetserver"
PP_ROLE="$PUPPET_VER""_master"
## You probably _don't_ want to change these ##
TEMP_DIR="setup-tmp" # if you change this it's worth adding the new value to your .gitignore if you are using vagrant
delete_on_exit=true
EYAML_PRIVATEKEY="/etc/puppetlabs/puppet/keys/private_key.pkcs7.pem"
EYAML_PUBLICKEY="/etc/puppetlabs/puppet/keys/public_key.pkcs7.pem"
R10K_YAML="/etc/puppetlabs/r10k/r10k.yaml" # temporary to get us up and running, Puppet will take over in due course
### END OF CONF ###
throw() {
printf '%s\n' "$1" >&2
exit 1
}
# Make sure only root can run our script
if [ "$(id -u)" != "0" ]; then
echo "Usage: sudo ${0##*/}" 1>&2
exit 1
fi
### ARGUMENT PARSER ###
while :; do
case $1 in
-h|--hostname)
if [ "$2" ]; then
NEWHOSTNAME="$2"
shift
else
throw 'ERROR: "-h|--hostname" requires a value'
fi
;;
-g|--gitrepo)
if [ "$2" ]; then
GITREPO="$2"
shift
else
throw 'ERROR: "-g|--gitrepo" requires a value'
fi
;;
-d|--domain)
if [ "$2" ]; then
DEFAULT_DOMAIN="$2"
shift
else
throw 'ERROR: "-d|--domain" requires a value'
fi
;;
-E|--puppetenv)
if [ "$2" ]; then
PUPPETENV="$2"
shift
else
throw 'ERROR: "-E|--puppetenv" requires a value'
fi
;;
-P|--puppetversion)
if ["$2"]; then
PUPPET_VER="$2"
shift
else
throw 'ERROR: "-P|--puppetversion" requires a value'
fi
;;
-C|--PUPPETSERVERCLASS)
if ["$2"]; then
PUPPETSERVERCLASS="$2"
shift
else
throw 'ERROR: "-C|--puppetserverclass requires a value'
fi
;;
*)
if [ $1 ]; then
throw "ERROR: unsupported parameter passed: '$1'"
else
break
fi
esac
shift
done
### END ARGUMENT PARSER ###
### START TEX-MEX PRE-REQS CHECKS ###
# this is just temporary - I'll find a better way
PUPPET_TEST='/opt/puppetlabs/puppet'
if [ -d "$PUPPET_TEST" ]; then
throw "It looks like Puppet is already installed on this machine."
fi
if [ -z "$DEFAULT_DOMAIN" ]; then
read -p "Enter your domain name (eg contoso.com): " DEFAULT_DOMAIN
fi
if [ -z "$GITREPO" ]; then
read -p "Enter in the git repo where your environments live: " GITREPO
fi
if [ -z "$PUPPETSERVERCLASS" ]; then
read -p "What is the name of your Puppetserver class: " PUPPETSERVERCLASS
fi
# Make sure we have a sensible hostname (could WHILE this to ensure we don't keep bombing out of the script)
if [ -z "$NEWHOSTNAME" ]; then
read -p "Enter a hostname for this machine: " NEWHOSTNAME
fi
if [[ "$NEWHOSTNAME" == *"puppetserver"* ]] || [[ "$NEWHOSTNAME" == *"puppetmaster"* ]]; then
throw "Cannot use PUPPETSERVER as hostname, this should be set as a CNAME in DNS to allow for easy upgrade paths"
fi
if [[ "$NEWHOSTNAME" != *".$DEFAULT_DOMAIN"* ]]; then
NEWHOSTNAME+=".${DEFAULT_DOMAIN}"
fi
# ensure we're not going to kill off an existing Puppet server!
HOST_CHECK=$(getent ahostsv4 $NEWHOSTNAME | awk '{print $1}' | head -1)
if ! [ "$HOST_CHECK" = "" ]; then
HOSTNAME_IP=$(hostname -I)
IP_ARR=($HOSTNAME_IP)
if ! [[ " ${IP_ARR[@]} " =~ " ${HOST_CHECK} " ]]; then
throw "$NEWHOSTNAME already seems to belong to: $HOST_CHECK"
fi
fi
if [ -z "$PUPPETENV" ]; then
read -p "Please enter the Puppet environment (git branch) to use: " PUPPETENV
fi
# Create dirs for copying our stuff too. (-p means we recurse and don't care if directories already exist)
mkdir -p "/etc/puppetlabs/puppet/keys" || exit 1
mkdir -p "/etc/puppetlabs/r10k" || exit 1
if [ -d "/vagrant" ];then
cd "/vagrant" # assume we're running in a vagrant box and want to do some testing!
delete_on_exit=false
fi
if [ ! -d "$TEMP_DIR" ];then
mkdir "$TEMP_DIR"
fi
if [ -f "$TEMP_DIR/private_key.pkcs7.pem" ]; then
echo "eyaml private key found"
cp "$TEMP_DIR/private_key.pkcs7.pem" $EYAML_PRIVATEKEY || exit 1
fi
if [ -f "$TEMP_DIR/public_key.pkcs7.pem" ]; then
echo "eyaml public key found"
cp "$TEMP_DIR/public_key.pkcs7.pem" $EYAML_PUBLICKEY || exit 1
fi
if [ -f "$TEMP_DIR/r10k.yaml" ]; then
echo "r10k yaml found"
cp "$TEMP_DIR/r10k.yaml" $R10K_YAML || exit 1
fi
if [ ! -f "$EYAML_PRIVATEKEY" ]; then
echo "The eyaml private key does not exist in /etc/puppetlabs/puppet/keys/"
echo "Please paste the private key below, press ctrl + d once you are finished to save."
echo "Please paste the key:"
EYAML_PRI=$(cat)
if [ ! "$EYAML_PRI" ]; then
throw "No key provided"
fi
echo "$EYAML_PRI" > "$EYAML_PRIVATEKEY" || exit 1
fi
if [ ! -f "$EYAML_PUBLICKEY" ]; then
echo "The eyaml public key does not exist in /etc/puppetlabs/puppet/keys/"
echo "Please paste the public key below, press ctrl + d once you are finished to save."
echo "Please paste the key:"
EYAML_PUB=$(cat)
if [ ! "$EYAML_PUB" ]; then
echo "No key provided"
exit 1
fi
echo "$EYAML_PUB" > "$EYAML_PUBLICKEY" || exit 1
fi
if [ ! -f "$R10K_YAML" ]; then
echo "The starter r10k yaml not exist in /etc/puppetlabs/r10k/"
echo "Please paste the yaml below, press ctrl + d once you are finished to save."
echo "Please paste the yaml:"
YAML=$(cat)
if [ ! "$YAML" ]; then
echo "No yaml provided"
exit 1
fi
echo "$YAML" > "$R10K_YAML" || exit 1
fi
if [ ! -d /root/.ssh ]; then
mkdir /root/.ssh || exit 1
chmod 700 /root/.ssh || exit 1
fi
### END TEX-MEX PRE-REQS CHECKS ###
### Start doing the things ###
echo "
All prerequisite checks have passed, this Puppet server will be configured with:
Hostname: $NEWHOSTNAME
Puppet Version: $PUPPET_VER
Source Control: $GITREPO
Starting Environment: $PUPPETENV
Puppet Server Class: $PUPPETSERVERCLASS
Extended Certificate Attributes:
Environment: $PP_ENVIRONMENT
Service: $PP_SERVICE
Role: $PP_ROLE
"
read -p "If you're happy press 'enter' to continue, otherwise press 'ctrl + c' to abort..."
echo "Setting hostname to $NEWHOSTNAME"
hostname $NEWHOSTNAME
echo $NEWHOSTNAME > /etc/hostname
echo "Adding Github to known hosts list"
KEYSCAN=`ssh-keyscan github.com 2> /dev/null`|| exit 1
echo "$KEYSCAN" >> /root/.ssh/known_hosts
echo "Generating new SSH key pair."
# Silently generate our key pair
if [ ! -f /root/.ssh/id_rsa.pub ]
then
cat /dev/zero | ssh-keygen -b 2048 -t rsa -q -C "$NEWHOSTNAME" -N "" > /dev/null
fi
echo "Please copy the following key into the deploy keys on your GitHub repo"
cat /root/.ssh/id_rsa.pub
read -p "Press enter to continue..."
# We don't want to clone everything as that would be dumb so let's just check we can at least clone with a bare repo.
echo "Testing key pair works on $GITREPO"
git clone --bare "$GITREPO" "$TEMP_DIR/gittest" || throw "Failed to clone $GITREPO. Are you sure you copied the key?"
rm -r "$TEMP_DIR/gittest" # clean up
cd "$TEMP_DIR"
dist=`awk -F= '/^NAME/{print $2}' /etc/os-release`
# TODO: Debian support?
if [ "$dist" == "\"CentOS Linux\"" ]; then
version=`awk -F= '/^VERSION_ID/{print $2}' /etc/os-release`
URL="https://yum.puppetlabs.com/puppet6/${PUPPET_VER}-release-el-${version//\"}.noarch.rpm"
echo "Fetching installer from $URL"
wget "$URL" || exit 1
rpm -Uvh ${PUPPET_VER}-release-el-${version//\"}.noarch.rpm || exit 1
echo "Installing Puppet Agent"
yum update || exit 1
yum install puppet-agent -y || exit 1
elif [ "$dist" == "\"Ubuntu\"" ]; then
RELEASE_NAME=`lsb_release -c -s`
URL="https://apt.puppetlabs.com/${PUPPET_VER}-release-${RELEASE_NAME}.deb"
echo "Fetching installer from $URL"
wget "$URL" || exit 1
dpkg -i ${PUPPET_VER}-release-${RELEASE_NAME}.deb || exit 1
apt-get update || exit 1
echo "installing Puppet Agent"
apt-get install puppet-agent || exit 1
else
throw "Not Ubuntu or CentOS. Aborting."
fi
# Add puppet to this session's PATH (hopefully the installer will sort it for future sessions)
export PATH=$PATH:/opt/puppetlabs/bin
# Set the environment
/opt/puppetlabs/bin/puppet config --section agent set environment $PUPPETENV
echo "extension_requests:" >> /etc/puppetlabs/puppet/csr_attributes.yaml
[ $PP_ENVIRONMENT ] && echo " pp_environment: $PP_ENVIRONMENT" >> /etc/puppetlabs/puppet/csr_attributes.yaml
[ $PP_SERVICE ] && echo " pp_service: $PP_SERVICE" >> /etc/puppetlabs/puppet/csr_attributes.yaml
[ $PP_ROLE ] && echo " pp_role: $PP_ROLE" >> /etc/puppetlabs/puppet/csr_attributes.yaml
# Make sure the contents of /root/.ssh are owned correctly
chown root:root /root/.ssh/* || exit 1
chmod 0600 /root/.ssh/* || exit 1
echo "Installing Ruby and Git"
apt install ruby git -y || exit 1
echo "Installing r10k"
gem install r10k || exit 1
if [ "$delete_on_exit" = true ]; then
rm -r $TEMP_DIR
fi
# We update all environments here as we may have nodes on different envs that we want to talk to our new server...
echo "Running r10k. This WILL take a while..."
/usr/local/bin/r10k deploy environment --puppetfile || throw "r10k failed to deploy, exit code: $?"
echo "Running puppet apply"
cd "/etc/puppetlabs/code/environments/$PUPPETENV" || throw "Failed to find /etc/puppetlabs/code/environments/$PUPPETENV. Are you sure your environment is valid?"
/opt/puppetlabs/bin/puppet apply --hiera_config="/etc/puppetlabs/code/environments/$PUPPETENV/hiera.bootstrap.yaml" --modulepath="./modules:./ext-modules" -e "include $PUPPETSERVERCLASS" || exit 1
echo "
Initial setup done, Puppet should now take over and do the rest.
Don't forget to:
* Create a DHCP reservation or static IP for this machine
* Merge your branch and change the Puppet environment back to 'production'
* Ensure eyaml keys are working correctly
"