forked from spring-projects/spring-petclinic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup-pipeline
224 lines (203 loc) · 8.53 KB
/
setup-pipeline
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
#!/bin/bash
# Provide next arguments in KEY=VALUE style:
#
# PROJECT_ID - GCP Project ID
# REGION - Region where all regional resources will bedeployed
# ZONE - Zone where all zonal resiurces will be deployed
# CLUSTER - Name of GKE cluster
# SQL_DATABASE - Spring-petclinic database name
# SQL_USERNAME - Username for connecting to spring-petclinic database
# SQL_PASSWORD - Password for connecting to spring-petclinic database
# DOCKER_USERNAME - Docker registry user name
# DOCKER_PASSWORD - Docker registry user password
# JENKINS_ADMIN_USERNAME - Jenkins admin username
# JENKINS_ADMIN_PASSWORD - Jenkins admin password
# DOMAIN - Global domain name for spring-petclinic CI environment
KEYS=(
"PROJECT_ID"
"REGION"
"ZONE"
"CLUSTER"
"SQL_DATABASE"
"SQL_USERNAME"
"SQL_PASSWORD"
"DOCKER_USERNAME"
"DOCKER_PASSWORD"
"JENKINS_ADMIN_USERNAME"
"JENKINS_ADMIN_PASSWORD"
"DOMAIN"
)
for ARGUMENT in "$@"; do
KEY="$(echo "${ARGUMENT}" | cut -f1 -d=)"
KEY_LENGTH=${#KEY}
VALUE="${ARGUMENT:${KEY_LENGTH}+1}"
declare "${KEY}"="${VALUE}"
done
for KEY in "${KEYS[@]}"; do
if [ -z ${!KEY+x} ]; then
printf "${KEY}: "
read "${KEY}"
fi
done
ACCOUNT="$(gcloud config get account)"
gcloud config set project "${PROJECT_ID}"
gcloud services enable \
compute.googleapis.com \
container.googleapis.com \
storage-api.googleapis.com \
sqladmin.googleapis.com \
servicenetworking.googleapis.com \
cloudresourcemanager.googleapis.com \
iam.googleapis.com \
dns.googleapis.com
mkdir build
openssl req -new -sha256 -nodes -newkey rsa:2048 \
-subj "/C=UA/CN=ProjectCA" \
-keyout ./build/ProjectCA.key \
-out ./build/ProjectCA.csr
openssl x509 -req -sha256 -in ./build/ProjectCA.csr \
-signkey ./build/ProjectCA.key \
-days 365 -out ./build/ProjectCA.crt
openssl genrsa -out ./build/project.com.key 2048
cp /etc/ssl/openssl.cnf ./build/openssl.cnf
cat <<EOF >> ./build/openssl.cnf
[ SAN ]
subjectAltName=DNS:*.project.com
EOF
openssl req -new -sha256 -key ./build/project.com.key \
-subj "/C=UA/O=Project/CN=*.project.com" -reqexts SAN \
-config ./build/openssl.cnf \
-out ./build/project.com.csr
openssl x509 -req -in ./build/project.com.csr \
-CA ./build/ProjectCA.crt \
-CAkey ./build/ProjectCA.key \
-CAcreateserial \
-out ./build/project.com.crt \
-days 500 -sha256 -extfile <(echo "subjectAltName=DNS:*.project.com")
gcloud compute ssl-certificates create project-cert \
--certificate ./build/project.com.crt \
--private-key ./build/project.com.key \
--region "${REGION}"
sudo cp ./build/ProjectCA.crt /usr/local/share/ca-certificates/ProjectCA.crt
sudo update-ca-certificates
sudo systemctl restart docker
cd ./terraform
terraform init
cat <<EOF > terraform.tfvars
project_id = "${PROJECT_ID}"
region = "${REGION}"
zone = "${ZONE}"
gke_cluster_name = "${CLUSTER}"
sql_database_name = "${SQL_DATABASE}"
sql_user_name = "${SQL_USERNAME}"
sql_user_password = "${SQL_PASSWORD}"
domain = "${DOMAIN}"
EOF
terraform plan -out ../build/tfplan
terraform apply ../build/tfplan
WIREGUARD_IP="$(terraform output -raw wireguard_server_public_ip)"
OS_LOGIN_USERNAME="$(terraform output -raw os_login_ssh_username)"
BUCKET_NAME="$(terraform output -raw docker_registry_storage_bucket)"
SQL_CONNECTION="$(terraform output -raw sql_connection_name)"
SQL_SA="$(terraform output -raw sql_service_account)"
NAMESERVERS="$(terraform output dns_name_servers)"
JENKINS_WEBHOOK_IP="$(terraform output -raw jenkins_webhook_static_ip)"
terraform output -raw os_login_sa_key > ../build/os-login-sa.json
terraform output -raw docker_registry_storage_sa_key > ../docker-registry-chart/service-account.json
terraform output -raw ansible_control_node_sa_key > ../build/ansible-sa.json
terraform output -raw gke_deploy_sa_key > ../build/gke-sa.json
cd ..
ssh-keygen -f ./build/os-login-ssh-key -N ""
gcloud auth activate-service-account --key-file ./build/os-login-sa.json
gcloud compute os-login ssh-keys add --key-file=./build/os-login-ssh-key.pub
gcloud config set account "${ACCOUNT}"
ssh-keygen -F "${WIREGUARD_IP}" || ssh-keyscan "${WIREGUARD_IP}" >> ~/.ssh/known_hosts
cat <<EOF > ./build/wg0-client.conf
[Interface]
Address = 10.0.10.2/32
PrivateKey = $(ssh -i ./build/os-login-ssh-key ${OS_LOGIN_USERNAME}@${WIREGUARD_IP} "sudo cat /etc/wireguard/client-private.key")
DNS = $(gcloud compute addresses list --filter='purpose:DNS_RESOLVER AND subnetwork:project-subnet' --format='get(address)')
MTU = 1380
[Peer]
PublicKey = $(ssh -i ./build/os-login-ssh-key ${OS_LOGIN_USERNAME}@${WIREGUARD_IP} "sudo cat /etc/wireguard/server-public.key")
Endpoint = ${WIREGUARD_IP}:51820
AllowedIPs = 10.0.10.0/24, 10.10.10.0/24, 10.0.0.0/28
PersistentKeepalive = 21
EOF
sudo wg-quick up ./build/wg0-client.conf
cp ./build/project.com.crt ./docker-registry-chart/project.com.crt
cp ./build/project.com.key ./docker-registry-chart/project.com.key
docker run --rm --entrypoint htpasswd httpd:2 -Bbn "${DOCKER_USERNAME}" "${DOCKER_PASSWORD}" > ./docker-registry-chart/htpasswd
gcloud container clusters get-credentials "${CLUSTER}" --region "${REGION}"
helm upgrade --install docker-registry ./docker-registry-chart/ \
--set storageBucketName="${BUCKET_NAME}" \
--namespace docker-registry \
--create-namespace
echo -n "Waiting for Docker registry"
until $(curl --output /dev/null --silent --fail https://docker-registry.project.com); do
echo -n '.'
done
echo ""
echo "${DOCKER_PASSWORD}" | docker login https://docker-registry.project.com -u "${DOCKER_USERNAME}" --password-stdin
docker build -t docker-registry.project.com/ansible:1.0.0 -f ./ansible/ansible.dockerfile ./ansible
docker push docker-registry.project.com/ansible:1.0.0
cp ./build/ProjectCA.crt ./jenkins/ProjectCA.crt
docker build -t docker-registry.project.com/jenkins:1.0.0 -f ./jenkins/jenkins.dockerfile --build-arg CERT_PATH=ProjectCA.crt ./jenkins
docker push docker-registry.project.com/jenkins:1.0.0
docker build -t docker-registry.project.com/gcloud-helm:1.0.0 -f ./jenkins/gcloud-helm.dockerfile ./jenkins
docker push docker-registry.project.com/gcloud-helm:1.0.0
for NAMESPACE in "jenkins" "petclinic-ci" "petclinic-qa"; do
kubectl create namespace "${NAMESPACE}"
kubectl create secret docker-registry registry-secret \
--docker-server=https://docker-registry.project.com \
--docker-username="${DOCKER_USERNAME}" \
--docker-password="${DOCKER_PASSWORD}" \
--namespace "${NAMESPACE}"
done
kubectl config set-context --current --namespace=jenkins
kubectl create secret generic ansible-ssh \
--from-literal username="${OS_LOGIN_USERNAME}" \
--from-file key=./build/os-login-ssh-key
kubectl create secret generic ansible-service-account --from-file key=./build/ansible-sa.json
kubectl create secret generic gke-service-account --from-file key=./build/gke-sa.json
kubectl create secret generic cluster-details \
--from-literal location="${REGION}" \
--from-literal project-id="${PROJECT_ID}" \
--from-literal name="${CLUSTER}"
kubectl create secret generic mysql-credentials \
--from-literal database="${SQL_DATABASE}" \
--from-literal username="${SQL_USERNAME}" \
--from-literal password="${SQL_PASSWORD}" \
--from-literal connection-name="${SQL_CONNECTION}" \
--from-literal service-account="${SQL_SA}"
kubectl create secret generic user-credentials \
--from-literal admin-username="${JENKINS_ADMIN_USERNAME}" \
--from-literal admin-password="${JENKINS_ADMIN_PASSWORD}"
kubectl create secret generic registry-credentials \
--from-literal username="${DOCKER_USERNAME}" \
--from-literal password="${DOCKER_PASSWORD}"
kubectl create secret generic lb-details --from-literal domain="${DOMAIN}"
kubectl create secret tls certs-secret \
--cert=./build/ProjectCA.crt \
--key=./build/ProjectCA.key
helm repo add jenkins https://charts.jenkins.io
helm repo update
helm upgrade --install jenkins jenkins/jenkins \
-f ./jenkins/config.yaml \
-f ./jenkins/credentials.yaml \
-f ./jenkins/pipelines.yaml
kubectl create secret tls certs-secret \
--cert=./build/ProjectCA.crt \
--key=./build/ProjectCA.key \
--namespace kube-system
kubectl apply -f ./certs/kubernetes.yaml
export ANSIBLE_HOST_KEY_CHECKING=False
sed -i -e "s;PROJECT_ID;${PROJECT_ID};" -e "s;ANSIBLE_SA_KEY_PATH;$(pwd)/build/os-login-sa.json;" ./ansible/inventory.gcp.yml
ansible-playbook -i ./ansible/inventory.gcp.yml \
--private-key ./build/os-login-ssh-key \
-u "${OS_LOGIN_USERNAME}" \
-e cert_path="$(pwd)/build/ProjectCA.crt" ./certs/ansible.yml
echo "Add nameservers to domain config:
${NAMESERVERS}"
echo "Create GitHub webhook with Push and Pull Request events to URL:
http://${JENKINS_WEBHOOK_IP}/github-webhook/"