forked from aws-samples/aws-pipeline-demo-with-tekton
-
Notifications
You must be signed in to change notification settings - Fork 0
/
install.sh
executable file
·239 lines (202 loc) · 15.2 KB
/
install.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
#!/bin/bash
set -e
# Define version for third party dependencies
export TEKTON_PIPELINE_VERSION="v0.26.0"
export TEKTON_TRIGGERS_VERSION="v0.14.2"
export TEKTON_DASHBOARD_VERSION="v0.18.1"
export CHARTMUSEUM_VERSION="3.1.0"
export AWS_LB_CONTROLLER_VERSION="1.2.3"
export AWS_EBS_CSI_DRIVER_VERSION="0.9.4"
export ARGOCD_VERSION="v2.0.4"
export EKS_VERSION="1.18"
# Check for prerequisites
for tool in aws kubectl eksctl aws-iam-authenticator kubectl helm jq envsubst base64
do
if ! [ -x "$(command -v $tool)" ]; then
echo "[ERROR] $(date +"%T") $tool is not installed. Please install $tool before running the script again" >&2
exit 1
fi
done
export AWS_AUTHENTICATED_IDENTITY=$(aws sts get-caller-identity | jq -r .Arn | cut -d "/" -f2)
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
export AWS_REGION=$(aws configure get region)
export TMP_FILE=$(mktemp)
export DOCKER_SCAN_SUGGEST=false
while true; do
read -p "Install resources as $AWS_AUTHENTICATED_IDENTITY within account $AWS_ACCOUNT_ID in region $AWS_REGION [Y/N] " yn
case $yn in
[Yy]* ) break;;
[Nn]* ) exit 1;;
* ) echo "[ERROR] $(date +"%T") Please answer yes [Y|y] or no [N|n]." >&2;;
esac
done
while true; do
read -p "Please enter your public ip address [XXX.XXX.XXX.XXX] " MY_IP_ADDRESS
if [[ $MY_IP_ADDRESS =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
export MY_IP_ADDRESS && break
else
echo "[ERROR] $(date +"%T") Please insert valid ip address [format: XXX.XXX.XXX.XXX]" >&2
fi
done
while true; do
read -p "Please enter the name of your EKS Cluster () " EKS_CLUSTER_NAME
EKS_CLUSTER_STACK="eksctl-${EKS_CLUSTER_NAME}-cluster"
if [[ $(aws cloudformation describe-stacks --stack-name="$EKS_CLUSTER_STACK" | jq -r '.Stacks[0].StackStatus') = "CREATE_COMPLETE" ]]; then
export EKS_CLUSTER_STACK && export EKS_CLUSTER_NAME && break
else
echo "[ERROR] $(date +"%T") Invalid Cluster Name provided or cluster not yet ready" >&2
fi
done
echo $EKS_CLUSTER_STACK
echo $EKS_CLUSTER_NAME
echo $AWS_REGION
# Generate GIT Credentials for CodeCommit
echo "[INFO] $(date +"%T") Create git credentials for user ${AWS_AUTHENTICATED_IDENTITY}..."
export TEKTON_DEMO_GIT_PASSWORD_RAW=$(aws iam create-service-specific-credential --service-name codecommit.amazonaws.com --user-name $AWS_AUTHENTICATED_IDENTITY | jq -r .ServiceSpecificCredential.ServicePassword)
export TEKTON_DEMO_GIT_PASSWORD=$(echo -n $TEKTON_DEMO_GIT_PASSWORD_RAW | jq -Rr @uri)
export TEKTON_DEMO_GIT_USERNAME=$(aws iam list-service-specific-credentials --service-name codecommit.amazonaws.com --user-name ${AWS_AUTHENTICATED_IDENTITY} | jq -r '.ServiceSpecificCredentials[] | select(.ServiceName == "codecommit.amazonaws.com") | .ServiceUserName')
# Create stack TetkonDemoBuckets
echo "[INFO] $(date +"%T") Create <<TektonDemoBucket>> Cloudformation Stack..."
aws cloudformation create-stack --stack-name="TektonDemoBuckets" --template-body file://cloudformation/demo-code-bucket.yaml --capabilities "CAPABILITY_IAM" > /dev/null
aws cloudformation wait stack-create-complete --stack-name="TektonDemoBuckets"
# Fetch required stack output variables
echo "[INFO] $(date +"%T") Fetch <<TektonDemoBucket>> Cloudformation Stack output variables..."
export TEKTON_DEMO_CHARTMUSEUM_BUCKET=$(aws cloudformation describe-stacks --stack-name TektonDemoBuckets | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "ChartmuseumBucket") | .OutputValue')
export TEKTON_DEMO_CHARTMUSEUM_POLICY=$(aws cloudformation describe-stacks --stack-name TektonDemoBuckets | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "PolicyArnForChartMuseumSa") | .OutputValue')
export TEKTON_DEMO_CODE_BUCKET=$(aws cloudformation describe-stacks --stack-name TektonDemoBuckets | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "CodeBucket") | .OutputValue')
# Package and upload helm-springboot master helm chart
echo "[INFO] $(date +"%T") Package helm master chart and upload to S3..."
helm package helm-springboot > /dev/null
aws s3 cp helm-springboot-0.1.0.tgz s3://${TEKTON_DEMO_CHARTMUSEUM_BUCKET}/ > /dev/null
rm -f helm-springboot-0.1.0.tgz
# Upload tekton-demo-app-build
echo "[INFO] $(date +"%T") Upload source files to S3..."
cat tekton-demo-app-build/pom.xml | envsubst | tee $TMP_FILE > /dev/null && mv $TMP_FILE tekton-demo-app-build/pom.xml
cd tekton-demo-app-build
zip -r tekton-pipeline-demo-app-code.zip . > /dev/null
aws s3 cp tekton-pipeline-demo-app-code.zip s3://${TEKTON_DEMO_CODE_BUCKET}/ > /dev/null
rm -f tekton-pipeline-demo-app-code.zip
cd ..
# Upload tekton-demo-app-deploy
echo "[INFO] $(date +"%T") Upload deploy files to S3..."
cd tekton-demo-app-deploy
zip -r tekton-pipeline-demo-deploy-code.zip . > /dev/null
aws s3 cp tekton-pipeline-demo-deploy-code.zip s3://${TEKTON_DEMO_CODE_BUCKET}/ > /dev/null
rm -f tekton-pipeline-demo-deploy-code.zip
cd ..
# Build and upload tekton-webhook-middleware
echo "[INFO] $(date +"%T") Compile webhook lambda and upload to S3..."
cd tekton-webhook-middleware
GOOS=linux GOARCH=amd64 go build -o tekton-webhook-middleware main.go > /dev/null
zip tekton-pipeline-demo-webhook-code.zip tekton-webhook-middleware > /dev/null
aws s3 cp tekton-pipeline-demo-webhook-code.zip s3://${TEKTON_DEMO_CODE_BUCKET}/ > /dev/null
rm -f tekton-pipeline-demo-webhook-code.zip
rm -f tekton-webhook-middleware
cd ..
# # Create the EKS Cluster
echo "[INFO] $(date +"%T") Configure EKS Cluster..."
cat eks-cluster-iam-config.yaml | envsubst | tee $TMP_FILE > /dev/null && mv $TMP_FILE eks-cluster-iam-config.yaml
eksctl utils associate-iam-oidc-provider --cluster=$EKS_CLUSTER_NAME --approve
eksctl create iamserviceaccount --config-file=eks-cluster-iam-config.yaml --approve
export TEKTON_DEMO_CLUSTER_SUBNETS=$(aws cloudformation describe-stacks --stack-name $EKS_CLUSTER_STACK | jq '.Stacks[0].Outputs[] | select(.OutputKey == "SubnetsPrivate") | .OutputValue')
export TEKTON_DEMO_CLUSTER_VPC=$(aws cloudformation describe-stacks --stack-name $EKS_CLUSTER_STACK | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "VPC") | .OutputValue')
export TEKTON_DEMO_CLUSTER_NODE_SG=$(aws cloudformation describe-stacks --stack-name $EKS_CLUSTER_STACK | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "ClusterSecurityGroupId") | .OutputValue')
# Create CF Stack "TektonDemoInfra"
echo "[INFO] $(date +"%T") Create <<TektonDemoInfra>> Cloudformation Stack..."
aws cloudformation create-stack --stack-name="TektonDemoInfra" --template-body file://cloudformation/demo-infra.yaml --parameters ParameterKey=TektonDemoSourceBucket,ParameterValue="${TEKTON_DEMO_CODE_BUCKET}" ParameterKey=TektonDemoClusterSubnets,ParameterValue="${TEKTON_DEMO_CLUSTER_SUBNETS}" ParameterKey=TektonDemoClusterVpc,ParameterValue="${TEKTON_DEMO_CLUSTER_VPC}" ParameterKey=AllowedIpAddress,ParameterValue="${MY_IP_ADDRESS}" --capabilities "CAPABILITY_IAM" > /dev/null
aws cloudformation wait stack-create-complete --stack-name="TektonDemoInfra"
export TEKTON_DEMO_CHARTMUSEUM_SG=$(aws cloudformation describe-stacks --stack-name TektonDemoInfra | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "ChartmuseumSecurityGroup") | .OutputValue')
export TEKTON_DEMO_DASHBOARD_SG=$(aws cloudformation describe-stacks --stack-name TektonDemoInfra | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "DashboardSecurityGroup") | .OutputValue')
export TEKTON_DEMO_APP_SG=$(aws cloudformation describe-stacks --stack-name TektonDemoInfra | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "AppSecurityGroup") | .OutputValue')
export TEKTON_DEMO_WEBHOOK_SG=$(aws cloudformation describe-stacks --stack-name TektonDemoInfra | jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "WebhookSecurityGroup") | .OutputValue')
# Update Security Group of Worker Nodes
echo "[INFO] $(date +"%T") Update EKS worker node security groups..."
aws ec2 authorize-security-group-ingress --group-id $TEKTON_DEMO_CLUSTER_NODE_SG --ip-permissions IpProtocol=tcp,FromPort=30000,ToPort=32767,UserIdGroupPairs=[{GroupId=$TEKTON_DEMO_DASHBOARD_SG}]
aws ec2 authorize-security-group-ingress --group-id $TEKTON_DEMO_CLUSTER_NODE_SG --ip-permissions IpProtocol=tcp,FromPort=30000,ToPort=32767,UserIdGroupPairs=[{GroupId=$TEKTON_DEMO_APP_SG}]
aws ec2 authorize-security-group-ingress --group-id $TEKTON_DEMO_CLUSTER_NODE_SG --ip-permissions IpProtocol=tcp,FromPort=30000,ToPort=32767,UserIdGroupPairs=[{GroupId=$TEKTON_DEMO_WEBHOOK_SG}]
aws ec2 authorize-security-group-ingress --group-id $TEKTON_DEMO_CLUSTER_NODE_SG --ip-permissions IpProtocol=tcp,FromPort=30000,ToPort=32767,UserIdGroupPairs=[{GroupId=$TEKTON_DEMO_CHARTMUSEUM_SG}]
# Build cloner image
echo "[INFO] $(date +"%T") Build cloner container image and upload to ECR..."
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com > /dev/null
docker build -t cloner ./docker/cloner > /dev/null
docker tag cloner:latest ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/cloner:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/cloner:latest > /dev/null
# Build maven-builder image
echo "[INFO] $(date +"%T") Build maven-build container image and upload to ECR..."
docker build -t maven-builder ./docker/maven-builder > /dev/null
docker tag maven-builder:latest ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/maven-builder:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/maven-builder:latest > /dev/null
# Install AWS EBS CSI Driver
echo "[INFO] $(date +"%T") Deploy aws-ebs-csi-driver [${AWS_EBS_CSI_DRIVER_VERSION}]..."
helm repo add aws-ebs-csi-driver https://kubernetes-sigs.github.io/aws-ebs-csi-driver > /dev/null
helm install -n kube-system aws-ebs-csi-driver aws-ebs-csi-driver/aws-ebs-csi-driver --version $AWS_EBS_CSI_DRIVER_VERSION --set enableVolumeResizing=true --set enableVolumeSnapshot=true --set serviceAccount.snapshot.create=false --set serviceAccount.controller.create=false --set serviceAccount.controller.name=ebs-csi-controller-sa --set serviceAccount.snapshot.name=ebs-csi-controller-sa > /dev/null
# Install AWS Load Balancer Controller
echo "[INFO] $(date +"%T") Deploy aws-load-balancer-controller [${AWS_LB_CONTROLLER_VERSION}]..."
helm repo add eks https://aws.github.io/eks-charts > /dev/null
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"
helm install -n kube-system aws-load-balancer-controller eks/aws-load-balancer-controller --version $AWS_LB_CONTROLLER_VERSION --set clusterName=tekton-pipeline-demo-cluster --set serviceAccount.create=false --set serviceAccount.name=aws-lb-controller-sa > /dev/null
###########################
# Install Tekton components
###########################
# Install Tekton Pipelines
echo "[INFO] $(date +"%T") Deploy Tekton Pipelines [${TEKTON_PIPELINE_VERSION}]..."
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/previous/${TEKTON_PIPELINE_VERSION}/release.yaml
# Install Tekton Triggers
echo "[INFO] $(date +"%T") Deploy Tekton Triggers [${TEKTON_TRIGGERS_VERSION}]..."
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/previous/${TEKTON_TRIGGERS_VERSION}/release.yaml
# Install Tekton Dashboard
echo "[INFO] $(date +"%T") Deploy Tekton Dashboard [${TEKTON_DASHBOARD_VERSION}]..."
kubectl apply --filename https://github.com/tektoncd/dashboard/releases/download/${TEKTON_DASHBOARD_VERSION}/tekton-dashboard-release.yaml
# Install Chartmuseum
echo "[INFO] $(date +"%T") Deploy Chartmuseum [${CHARTMUSEUM_VERSION}]..."
helm repo add chartmuseum https://chartmuseum.github.io/charts > /dev/null
cat chartmuseum-values.yaml | envsubst | tee $TMP_FILE > /dev/null && mv $TMP_FILE chartmuseum-values.yaml
helm install -n support chartmuseum chartmuseum/chartmuseum --version $CHARTMUSEUM_VERSION -f chartmuseum-values.yaml > /dev/null
# Install ArgoCD
echo "[INFO] $(date +"%T") Deploy ArgoCD [${ARGOCD_VERSION}]..."
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/${ARGOCD_VERSION}/manifests/install.yaml
# Patch K8S SVCs
kubectl patch svc tekton-dashboard -n tekton-pipelines -p '{"spec": {"type": "NodePort"}}'
kubectl patch svc chartmuseum -n support -p '{"spec": {"type": "NodePort"}}'
kubectl -n argocd delete cm argocd-cm
kubectl -n argocd delete svc argocd-server
# INSTALL TEKTON DEMO
echo "[INFO] $(date +"%T") Deploy resources related to the demo..."
cat tekton-pipeline-demo-k8s-artifacts/values.yaml | envsubst | tee $TMP_FILE > /dev/null && mv $TMP_FILE tekton-pipeline-demo-k8s-artifacts/values.yaml
helm install tekton-pipeline-demo-k8s-artifacts -f tekton-pipeline-demo-k8s-artifacts/values.yaml --generate-name > /dev/null
sleep 30
# Adjust Tekton Webhook
echo "[INFO] $(date +"%T") Update webhook lambda function..."
export TEKTON_DEMO_WEBHOOK_URL=$(aws elbv2 describe-load-balancers | jq -r '.LoadBalancers[] | select(.DNSName | contains("webhook")) | .DNSName')
aws lambda update-function-configuration --function-name=TektonPipelineDemoWebhook --environment Variables={TEKTON_WEBHOOK_URL=http://${TEKTON_DEMO_WEBHOOK_URL}} > /dev/null
export TEKTON_DEMO_CHARTMUSEUM_URL=$(aws elbv2 describe-load-balancers | jq -r '.LoadBalancers[] | select(.DNSName | contains("chartmuseum")) | .DNSName')
echo "[INFO] $(date +"%T") Update manifest files within deploy repository..."
mkdir git-clone
cd git-clone
git clone https://${TEKTON_DEMO_GIT_USERNAME}:${TEKTON_DEMO_GIT_PASSWORD}@git-codecommit.${AWS_REGION}.amazonaws.com/v1/repos/tekton-demo-app-deploy > /dev/null
cd tekton-demo-app-deploy
cat values.yaml | envsubst | tee $TMP_FILE > /dev/null && mv $TMP_FILE values.yaml
cat requirements.yaml | envsubst | tee $TMP_FILE > /dev/null && mv $TMP_FILE requirements.yaml
git add values.yaml
git add requirements.yaml
git commit -m "[AUTO_UPDATE]" > /dev/null
git push > /dev/null
cd ../..
rm -rf git-clone
echo "[INFO] $(date +"%T") Trigger initial pipelinerun..."
aws codecommit test-repository-triggers --repository-name tekton-demo-app-build --triggers name=LambdaFunctionTrigger,destinationArn=$(aws codecommit get-repository-triggers --repository-name tekton-demo-app-build | jq -r .triggers[0].destinationArn),events=all,branches=master,customData=tekton-demo-app-build > /dev/null
TEKTON_DEMO_ARGOCD_PW=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
TEKTON_DEMO_ARGOCD_URL=$(kubectl -n argocd get svc argocd-server -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
TEKTON_DEMO_DASHBOARD_URL=$(aws elbv2 describe-load-balancers | jq -r '.LoadBalancers[] | select(.DNSName | contains("dashboard")) | .DNSName')
TEKTON_DEMO_APP_URL=$(aws elbv2 describe-load-balancers | jq -r '.LoadBalancers[] | select(.DNSName | contains("apps")) | .DNSName')
echo "[INFO] $(date +"%T") Display output values..."
echo "[INFO] DEMO APP => http://${TEKTON_DEMO_APP_URL}"
echo "[INFO] TEKTON DASHBOARD => http://${TEKTON_DEMO_DASHBOARD_URL}"
echo "[INFO] ARGOCD => http://${TEKTON_DEMO_ARGOCD_URL}"
echo "[INFO] SOURCE REPO => https://git-codecommit.${AWS_REGION}.amazonaws.com/v1/repos/tekton-demo-app-build"
echo "[INFO] GIT USERNAME => ${TEKTON_DEMO_GIT_USERNAME}"
echo "[INFO] GIT PASWORD => ${TEKTON_DEMO_GIT_PASSWORD}"
echo "[INFO] ARGOCD USERNAME => admin"
echo "[INFO] ARGOCD PASSWORD => ${TEKTON_DEMO_ARGOCD_PW}"
echo "[INFO] $(date +"%T") Successfully installed demo environment!"