· 6 years ago · Jun 05, 2019, 03:54 PM
1AWSTemplateFormatVersion: '2010-09-09'
2Description: AWS Cloudformation template to create an EC2 instance, installs GitLab
3 and creates ELB. **WARNING** This template creates an Amazon EC2 instance. You will
4 be billed for the AWS resources used if you create a stack from this template.
5Parameters:
6 # OAuthAppId:
7 # Description: The Application Id for OAuth authentication
8 # Type: String
9 # Default: ""
10 # OAuthSecret:
11 # Description: The Application Secret for OAuth authentication
12 # Type: String
13 # Default: ""
14 # OAuthServer:
15 # Description: The URL for OAuth authentication
16 # Type: String
17 # Default: ""
18 # EnableCognito:
19 # Description: Whether I should enable https.
20 # Default: false
21 # Type: String
22 # AllowedValues: [true, false]
23 EnableGitSSH:
24 Description: Whether I should enable git+ssh.
25 Default: false
26 Type: String
27 AllowedValues: [true, false]
28 GitLabCommunityAMI:
29 Type: String
30 InstanceType:
31 Description: GitLab server EC2 instance type
32 Type: String
33 Default: m4.xlarge
34 AllowedValues:
35 - t2.medium
36 - t3.medium
37 - t2.large
38 - m4.large
39 - m4.xlarge
40 - m4.2xlarge
41 - m4.4xlarge
42 ConstraintDescription: must be a valid EC2 instance type.
43 InstanceStorageSize:
44 Description: GitLab server storage size (in GBs)
45 Type: Number
46 Default: '10'
47 InstanceStorageType:
48 Description: 'GitLab server storage type. Allowed values are: standard, io1, gp2.'
49 Type: String
50 Default: standard
51 AllowedValues:
52 - standard
53 - io1
54 - gp2
55 InstanceStorageIOPS:
56 Description: GitLab server storage IOPS. Used only when storage type is set to
57 io1.
58 Type: Number
59 MinValue: '100'
60 MaxValue: '20000'
61 GitLabDataStorageSize:
62 Description: GitLab storage size for data (in GBs)
63 Type: Number
64 Default: '80'
65 GitLabDataStorageType:
66 Description: 'GitLab server storage type. Allowed values are: standard, io1, gp2.'
67 Type: String
68 Default: standard
69 AllowedValues:
70 - standard
71 - io1
72 - gp2
73 GitLabDataStorageIOPS:
74 Description: GitLab server storage IOPS. Used only when storage type is set to
75 io1.
76 Type: Number
77 Default: '400'
78 MinValue: '100'
79 MaxValue: '20000'
80 KeyName:
81 Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
82 Type: AWS::EC2::KeyPair::KeyName
83 ConstraintDescription: Can contain only ASCII characters.
84 VpcId:
85 Description: GitLab server VPC
86 Type: AWS::EC2::VPC::Id
87 VPCCIDR:
88 Description: CIDR block for the VPC
89 Type: String
90 PrivateSubnet1ID:
91 Description: GitLab server subnet 1
92 Type: AWS::EC2::Subnet::Id
93 PrivateSubnet2ID:
94 Description: GitLab server subnet 2
95 Type: AWS::EC2::Subnet::Id
96 PublicSubnet1ID:
97 Description: Elastic load balancer subnet 1
98 Type: AWS::EC2::Subnet::Id
99 PublicSubnet2ID:
100 Description: Elastic load balancer subnet 2
101 Type: AWS::EC2::Subnet::Id
102 GitLabPassword:
103 Description: GitLab root password
104 NoEcho: 'true'
105 Type: String
106 GitLabLicenseType:
107 AllowedValues:
108 - Community
109 - Enterprise
110 ConstraintDescription: Community or Enterprise
111 Default: Enterprise
112 Description: GitLab license type to install
113 Type: String
114 GitLabRunnerToken:
115 Description: Registration token for GitLab Runner. Registration token must contain
116 exactly 20 alphanumeric characters
117 AllowedPattern: ^[a-zA-Z0-9]*$
118 Type: String
119 MinLength: '20'
120 MaxLength: '20'
121 GitLabSpotPrice:
122 Description: If you want to use spot instance
123 Type: String
124 Default: <NONE>
125 RDSUsername:
126 Description: The user name that is associated with the master user account for
127 the RDS that is being created
128 Type: String
129 RDSDatabaseName:
130 Description: Database name
131 Type: String
132 RDSHost:
133 Description: Database host
134 Type: String
135 RDSPort:
136 Description: Databse port
137 Type: String
138 RedisEndpoint:
139 Description: Redis endpoint
140 Type: String
141 RedisPort:
142 Description: Redis port
143 Type: String
144 NumWebServerInstances:
145 Description: Number or web server instances in Auto scaling group
146 Type: Number
147 ElasticsearchEndpoint:
148 Description: Elasticsearch endpoint
149 Default: ''
150 Type: String
151 SmtpAddress:
152 AllowedValues:
153 - email-smtp.us-east-1.amazonaws.com
154 - email-smtp.us-west-2.amazonaws.com
155 - email-smtp.eu-west-1.amazonaws.com
156 Default: email-smtp.us-east-1.amazonaws.com
157 Description: Address of AWS SES SMTP server
158 Type: String
159 SmtpUserName:
160 Description: SMTP user name
161 Type: String
162 SmtpPassword:
163 Description: SMTP password
164 Type: String
165 SmtpDomain:
166 Description: SMTP domain
167 Type: String
168 AvailabilityZone:
169 Description: Availability Zone
170 Type: String
171 InstanceProfileName:
172 Description: Name of instance profile with roles
173 Type: String
174 HostedZoneName:
175 Default: <NONE>
176 Description: Name of Hosted Zone within which the Quick Start will create convenience
177 DNS entries for AWS Resources created by the Quick Start. If you do not wish
178 to create convenience DNS entries or are not using AWS Route53 for DNS, enter
179 '<NONE>', otherwise enter the Hosted Zone name including the trailing period,
180 for example 'dev.example.com.'.
181 Type: String
182 RootStackName:
183 Description: Name of Top-Level Stack
184 Type: String
185 EnableHttps:
186 Description: Whether I should enable https.
187 Default: false
188 Type: String
189 AllowedValues: [true, false]
190 SSLCertificateArn:
191 Description: The ARN of the SSL certificate
192 Type: String
193 EnableVPN:
194 Description: Whether I should enable OpenVPN.
195 Default: false
196 Type: String
197 AllowedValues: [true, false]
198 S3BackupBucket:
199 Type: String
200 S3ArtifactsBucket:
201 Type: String
202 QSS3BucketName:
203 Type: String
204 QSS3KeyPrefix:
205 Type: String
206 KMSKeyId:
207 Type: String
208 MaintenanceWindowServiceRole:
209 Type: String
210 BackupCronExpression:
211 Type: String
212 AccessKeyId:
213 Description: Runner Access Key ID
214 Type: String
215 AccessKeySecret:
216 Description: Runner Access Key Secret
217 Type: String
218 CronGitLabStartAutoscaling:
219 Type: String
220 CronGitLabStopAutoscaling:
221 Type: String
222Conditions:
223 # ShouldEnableCognito:
224 # !Equals [true, !Ref EnableCognito]
225 ShouldEnableGitSSH:
226 !Equals [true, !Ref EnableGitSSH]
227 ShouldEnableVPN:
228 !Equals [true, !Ref EnableVPN]
229 ShouldEnableHttps:
230 !Equals [true, !Ref EnableHttps]
231 GitLabEnterpriseCondition: !Equals
232 - !Ref 'GitLabLicenseType'
233 - Enterprise
234 GitLabStorageWithIOPSCondition: !Equals
235 - !Ref 'InstanceStorageType'
236 - io1
237 GitLabDataStorageWithIOPSCondition: !Equals
238 - !Ref 'GitLabDataStorageType'
239 - io1
240 HostedZoneIsSpecifiedCondition: !Not
241 - !Equals
242 - !Ref 'HostedZoneName'
243 - <NONE>
244 ShouldHaveSpotInstance: !Not
245 - !Equals
246 - !Ref 'GitLabSpotPrice'
247 - <NONE>
248Resources:
249 GitLabBackupSSMCommand:
250 Type: "AWS::SSM::Document"
251 Properties:
252 DocumentType: "Command"
253 Content:
254 schemaVersion: "2.2"
255 description: ""
256 parameters:
257 ResponseUrl:
258 type: String
259 default: ""
260 ResponseBody:
261 type: String
262 default: ""
263 mainSteps:
264 - action: "aws:runShellScript"
265 name: "backup_Gitlab"
266 inputs:
267 runCommand:
268 - "/etc/gitlab/gitlab-backup.sh"
269 - action: "aws:runShellScript"
270 name: "notify_CloudFormation"
271 inputs:
272 runCommand:
273 - "[ -z '{{ResponseUrl}}' ] || /usr/bin/curl -v -H 'Content-Type: ' -X PUT -d '{{ResponseBody}}' '{{ResponseUrl}}'"
274 GitLabRestoreSSMCommand:
275 Type: "AWS::SSM::Document"
276 Properties:
277 DocumentType: "Command"
278 Content:
279 schemaVersion: "2.2"
280 description: ""
281 mainSteps:
282 - action: "aws:runShellScript"
283 name: "backup_Gitlab"
284 inputs:
285 runCommand:
286 - "/etc/gitlab/gitlab-restore.sh"
287 - action: "aws:runShellScript"
288 name: "terminate_runners"
289 inputs:
290 runCommand:
291 - !Sub "aws ec2 terminate-instances --region ${AWS::Region} --instance-ids `aws ec2 describe-instances --region ${AWS::Region} --query 'Reservations[].Instances[].InstanceId' --filters 'Name=tag:aws:cloudformation:logical-id,Values=RunnerAutoScalingGroup' --output text`"
292 MaintenanceWindow:
293 Type: AWS::SSM::MaintenanceWindow
294 Properties:
295 Description: Backup Gitlab Maintenance windo
296 AllowUnassociatedTargets: false
297 Cutoff: 1
298 Schedule: !Ref 'BackupCronExpression'
299 Duration: 2
300 Name: daily-gitlab-backup
301 MaintenanceWindowTarget:
302 Type: AWS::SSM::MaintenanceWindowTarget
303 Properties:
304 Description: Server Fleet Management Solution Instances
305 WindowId: !Ref MaintenanceWindow
306 ResourceType: INSTANCE
307 Targets:
308 - Key: tag:Name
309 Values:
310 - GitLabApp
311 MaintenanceWindowTask:
312 Type: AWS::SSM::MaintenanceWindowTask
313 Properties:
314 ServiceRoleArn: !Ref MaintenanceWindowServiceRole
315 MaxErrors: 1
316 WindowId: !Ref MaintenanceWindow
317 TaskArn: !Ref GitLabBackupSSMCommand
318 MaxConcurrency: 100%
319 Priority: 1
320 TaskType: RUN_COMMAND
321 Targets:
322 - Values:
323 - !Ref MaintenanceWindowTarget
324 Key: WindowTargetIds
325
326 WebServerAutoScalingGroup:
327 Type: AWS::AutoScaling::AutoScalingGroup
328 Properties:
329 LaunchConfigurationName: !Ref 'WebServerLaunchConfiguration'
330 VPCZoneIdentifier:
331 - !Ref 'PrivateSubnet1ID'
332 MinSize: !Ref 'NumWebServerInstances'
333 MaxSize: !Ref 'NumWebServerInstances'
334 Cooldown: '300'
335 DesiredCapacity: !Ref 'NumWebServerInstances'
336 TargetGroupARNs:
337 - !Ref 'GitlabElasticLoadBalancerTargetGroup'
338 - !Ref 'GitlabElasticInternalLoadBalancerTargetGroup'
339 - !If
340 - ShouldEnableGitSSH
341 - !Ref 'GitlabSSHNLBTargetGroup'
342 - !Ref 'AWS::NoValue'
343 Tags:
344 - Key: Name
345 Value: GitLabApp
346 PropagateAtLaunch: 'true'
347 HealthCheckGracePeriod: 600
348 HealthCheckType: ELB
349 CreationPolicy:
350 ResourceSignal:
351 Count: !Ref 'NumWebServerInstances'
352 Timeout: PT25M
353 WebServerScheduledUptime:
354 Type: AWS::AutoScaling::ScheduledAction
355 Properties:
356 AutoScalingGroupName: !Ref 'WebServerAutoScalingGroup'
357 MinSize: !Ref 'NumWebServerInstances'
358 MaxSize: !Ref 'NumWebServerInstances'
359 Recurrence: !Ref CronGitLabStartAutoscaling
360 WebServerScheduledDowntime:
361 Type: AWS::AutoScaling::ScheduledAction
362 Properties:
363 AutoScalingGroupName: !Ref 'WebServerAutoScalingGroup'
364 MinSize: 0
365 MaxSize: 0
366 Recurrence: !Ref CronGitLabStopAutoscaling
367 GitLabAPIToken:
368 Type: Custom::Secret
369 Properties:
370 Name: '/gitlab/apitoken'
371 KeyAlias: alias/aws/ssm
372 Alphabet: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
373 Length: 30
374 ReturnSecret: true
375 ServiceToken: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:binxio-cfn-secret-provider'
376 WebServerLaunchConfiguration:
377 Type: AWS::AutoScaling::LaunchConfiguration
378 Metadata:
379 Comment: Install GitLab application
380 AWS::CloudFormation::Authentication:
381 S3AccessCreds:
382 type: S3
383 accessKeyId: !Ref AccessKeyId
384 secretKey: !Ref AccessKeySecret
385 AWS::CloudFormation::Init:
386 config:
387 files:
388 /etc/cloudwatchlog.conf:
389 content: !Join
390 - "\n"
391 - - '[general]'
392 - state_file = /var/lib/awslogs/agent-state
393 - '[/var/log/gitlab/gitlab-rails/application.log]'
394 - 'file = /var/log/gitlab/gitlab-rails/application.log'
395 - buffer_duration = 5000
396 - log_group_name = gitlab
397 - log_stream_name = application
398 - initial_position = start_of_file
399 /etc/cron.d/gitlab-monitoring:
400 content: !Join
401 - "\n"
402 - - '*/5 * * * * root /home/ubuntu/aws-scripts-mon/mon-put-instance-data.pl --mem-avail --mem-util --disk-space-util --disk-path=/var/opt/gitlab'
403 - ""
404 /etc/gitlab/gitlab-token.sh:
405 content: !Join
406 - "\n"
407 - - "#!/bin/bash"
408 - !Sub '/opt/gitlab/bin/gitlab-rails r "token = PersonalAccessToken.new(user: User.where(username: ''root'').first, name: ''api token'', token_digest: ''${GitLabAPIToken.Secret}'', scopes: [''api'']); token.save"''!'' || true'
409 /etc/gitlab/gitlab-backup.sh:
410 content: !Join
411 - "\n"
412 - - "#!/bin/bash"
413 - '/opt/gitlab/bin/gitlab-rake gitlab:backup:create CRON=1'
414 - !Sub '/usr/local/bin/aws s3 cp /var/opt/gitlab/gitlab-secrets.json s3://${S3BackupBucket}/gitlab-secrets.json'
415 - 'export PGDATABASE=sonarqube'
416 - 'export PGUSER=rdsuser'
417 - 'export PGPASSWORD=`/usr/local/bin/aws ssm get-parameter --name /sonarqube/PGPASSWD --region eu-west-1 --with-decryption --output text --query Parameter.Value`'
418 - !Sub 'export PGHOST=postgres-sonarqube.${RootStackName}.${HostedZoneName}'
419 - 'SONARQUBEBACKUPFILE=sonarqube-db-$(date +%d-%m-%y).dump'
420 - 'SONARQUBEBACKUP=/var/opt/gitlab/$SONARQUBEBACKUPFILE'
421 - '/opt/gitlab/embedded/bin/pg_dump -Fc sonarqube -f $SONARQUBEBACKUP'
422 - !Sub '/usr/local/bin/aws s3 cp $SONARQUBEBACKUP s3://${S3BackupBucket}/$SONARQUBEBACKUPFILE'
423 - rm $SONARQUBEBACKUP
424 - ""
425 /etc/gitlab/gitlab-restore.sh:
426 content: !Join
427 - "\n"
428 - - "#!/bin/bash"
429 - "set -x"
430 - !Sub "export LAST_S3_GITLAB_BACKUP=`/usr/local/bin/aws s3 ls ${S3BackupBucket} | grep 'gitlab_backup' | sort | tail -n 1 | awk '{print $4}'`"
431 - !Sub "export LAST_S3_SONARQUBE_BACKUP=`/usr/local/bin/aws s3 ls ${S3BackupBucket} | grep 'sonarqube' | sort | tail -n 1 | awk '{print $4}'`"
432 - "export LAST_BACKUP=`echo $LAST_S3_GITLAB_BACKUP | sed 's/_gitlab_backup.tar//g'`"
433 - !Sub "export AUTOSCALING_GROUP_NAME=`aws autoscaling describe-auto-scaling-groups --region ${AWS::Region} --query 'AutoScalingGroups[].[AutoScalingGroupName]' --output text | grep 'WebServerAutoScalingGroup'`"
434 - !Sub '/usr/local/bin/aws s3 cp s3://${S3BackupBucket}/gitlab-secrets.json /var/opt/gitlab/gitlab-secrets.json'
435 - !Sub '/usr/local/bin/aws s3 cp s3://${S3BackupBucket}/$LAST_S3_GITLAB_BACKUP /var/opt/gitlab/backups/$LAST_S3_GITLAB_BACKUP'
436 - !Sub '/usr/local/bin/aws s3 cp s3://${S3BackupBucket}/$LAST_S3_SONARQUBE_BACKUP /var/opt/gitlab/backups/$LAST_S3_SONARQUBE_BACKUP'
437 - !Sub '/usr/local/bin/aws autoscaling suspend-processes --auto-scaling-group-name $AUTOSCALING_GROUP_NAME --region ${AWS::Region}'
438 - /usr/bin/gitlab-ctl stop unicorn
439 - /usr/bin/gitlab-ctl stop sidekiq
440 - /usr/bin/gitlab-rake gitlab:backup:restore force=yes BACKUP=$LAST_BACKUP
441 - /usr/bin/gitlab-ctl start unicorn
442 - /usr/bin/gitlab-ctl start sidekiq
443 - bash /etc/gitlab/gitlab-token.sh
444 - !Sub '/usr/local/bin/aws autoscaling resume-processes --auto-scaling-group-name $AUTOSCALING_GROUP_NAME --region ${AWS::Region}'
445 - 'export PGDATABASE=sonarqube'
446 - 'export PGUSER=rdsuser'
447 - 'export PGPASSWORD=`/usr/local/bin/aws ssm get-parameter --name /sonarqube/PGPASSWD --region eu-west-1 --with-decryption --output text --query Parameter.Value`'
448 - !Sub 'export PGHOST=postgres-sonarqube.${RootStackName}.${HostedZoneName}'
449 - '/opt/gitlab/embedded/bin/pg_restore -v -c -d $PGDATABASE /var/opt/gitlab/backups/$LAST_S3_SONARQUBE_BACKUP || true'
450 - !Sub "export SONARQUBE_SERVICE=`/usr/local/bin/aws ecs list-services --region ${AWS::Region} --cluster sonarqube --query '[serviceArns]' --output text`"
451 - !Sub "/usr/local/bin/aws ecs update-service --service $SONARQUBE_SERVICE --region ${AWS::Region} --cluster sonarqube --force-new-deployment"
452 - ""
453 /etc/gitlab/gitlab-init.rb:
454 content: !Join
455 - "\n"
456 - - !Sub 'gitlab_rails[''initial_root_password''] = "${GitLabPassword}"'
457 - gitlab_rails['db_adapter'] = "postgresql"
458 - gitlab_rails['db_encoding'] = "unicode"
459 - !Sub 'gitlab_rails[''db_database''] = "${RDSDatabaseName}"'
460 - !Sub 'gitlab_rails[''db_username''] = "${RDSUsername}"'
461 - !Sub 'gitlab_rails[''db_host''] = "${RDSHost}"'
462 - !Sub 'gitlab_rails[''db_port''] = "${RDSPort}"'
463 - !Sub 'gitlab_rails[''redis_host''] = "${RedisEndpoint}"'
464 - !Sub 'gitlab_rails[''redis_port''] = "${RedisPort}"'
465 - gitlab_rails['smtp_enable'] = true
466 - !Sub 'gitlab_rails[''smtp_address''] = "${SmtpAddress}"'
467 - gitlab_rails['smtp_port'] = 587
468 - !Sub 'gitlab_rails[''smtp_user_name''] = "${SmtpUserName}"'
469 - !Sub 'gitlab_rails[''smtp_password''] = "${SmtpPassword}"'
470 - !Sub 'gitlab_rails[''smtp_domain''] = "${SmtpDomain}"'
471 - gitlab_rails['smtp_authentication'] = "login"
472 - gitlab_rails['smtp_enable_starttls_auto'] = true
473 - !Sub 'gitlab_rails[''gitlab_email_from''] = "gitlab@${SmtpDomain}"'
474 - !Sub 'gitlab_rails[''gitlab_email_reply_to''] = "noreply@${SmtpDomain}"'
475 - gitlab_rails['artifacts_enabled'] = true
476 - gitlab_rails['artifacts_object_store_enabled'] = true
477 - gitlab_rails['artifacts_object_store_direct_upload'] = true
478 - !Sub 'gitlab_rails[''artifacts_object_store_remote_directory''] = "${S3ArtifactsBucket}"'
479 - gitlab_rails['artifacts_object_store_connection'] = {
480 - "'provider' => 'AWS',"
481 - !Sub '''region'' => ''${AWS::Region}'','
482 - "'use_iam_profile' => 'true' }"
483 - !Sub 'gitlab_rails[''initial_shared_runners_registration_token'']
484 = "${GitLabRunnerToken}"'
485 - "\npostgresql['enable'] = false\n"
486 - nginx['real_ip_trusted_addresses'] = [ '10.0.0.0/8' ]
487 - nginx['real_ip_header'] = 'X-Forwarded-For'
488 - nginx['real_ip_recursive'] = 'on'
489 - !If [ShouldEnableHttps, "nginx['redirect_http_to_https'] = true\n" , "" ]
490 - !If [ShouldEnableHttps, "nginx['listen_https'] = false\n" , "" ]
491 - !If [ShouldEnableHttps, "nginx['redirect_http_to_https_port'] = 80\n" , "" ]
492 - !If [ShouldEnableHttps, "nginx['listen_port'] = 80\n" , "" ]
493 # - !If
494 # - ShouldEnableCognito
495 # - !Join
496 # - "\n"
497 # - - gitlab_rails['omniauth_enabled'] = true
498 # - gitlab_rails['omniauth_allow_single_sign_on'] = true
499 # - gitlab_rails['omniauth_sync_email_from_provider'] = 'oauth2_generic'
500 # - gitlab_rails['omniauth_block_auto_created_users'] = false
501 # - gitlab_rails['omniauth_providers'] = [
502 # - "{ 'name' => 'oauth2_generic',"
503 # - !Sub "'app_id' => '${OAuthAppId}',"
504 # - !Sub "'app_secret' => '${OAuthSecret}',"
505 # - "'args' => {"
506 # - "client_options: {"
507 # - !Sub "'site' => '${OAuthServer}/login',"
508 # - !Sub "'authorize_url' => '${OAuthServer}/oauth2/authorize',"
509 # - !Sub "'token_url' => '${OAuthServer}/oauth2/token',"
510 # - "'user_info_url' => '/oauth2/userInfo'"
511 # - "},"
512 # - "user_response_structure: {"
513 # - "id_path: 'sub',"
514 # - "root_path: [],"
515 # - "attributes: {"
516 # - "nickname: 'preferred_username', "
517 # - "email: 'email'"
518 # - "},"
519 # - "},"
520 # - "name: 'AWSCognito',"
521 # - "strategy_class: 'OmniAuth::Strategies::OAuth2Generic'"
522 # - "}"
523 # - "}"
524 # - "]\n"
525 # - ""
526 - "\n"
527 - "gitlab_rails['backup_upload_connection'] = {"
528 - "'provider' => 'AWS',"
529 - !Sub "'region' => '${AWS::Region}',"
530 - "# If using an IAM Profile, don't configure aws_access_key_id & aws_secret_access_key"
531 - "'use_iam_profile' => true"
532 - "}"
533 - !Sub "gitlab_rails['backup_upload_remote_directory'] = '${S3BackupBucket}'"
534 - "\n"
535
536 /etc/gitlab/gitlab-urls.sh:
537 content: !Join
538 - "\n"
539 - - '# This file helps in creating urls for GitLab
540 from HostedZoneName. This script removes dot from last position
541 of a HostedZoneName string. Result of this script is append to
542 gitlab.rb file.'
543 - '#!/bin/bash -x'
544 - 'rdsPassword=`aws ssm get-parameter --name /gitlab/PGPASSWD --region eu-west-1 --with-decryption --output text --query Parameter.Value`'
545 - "echo \"gitlab_rails['db_password'] = '$rdsPassword'\""
546 - !If
547 - HostedZoneIsSpecifiedCondition
548 - !Sub 'host=`echo ${HostedZoneName} | sed ''s/.$//''`'
549 - ''
550 - !If
551 - HostedZoneIsSpecifiedCondition
552 - !Join
553 - ''
554 - - !If [ShouldEnableHttps, "echo \"external_url 'https://" , "echo \"external_url 'http://" ]
555 - !Ref 'RootStackName'
556 - .$host'"
557 - !Join
558 - ''
559 - - echo "external_url 'http://
560 - !GetAtt 'GitlabElasticApplicationLoadBalancer.DNSName'
561 - '''"'
562 - !If
563 - HostedZoneIsSpecifiedCondition
564 - !If [ShouldEnableGitSSH,!Sub "echo \"gitlab_rails['gitlab_ssh_host']='ssh.${RootStackName}.$host'\"", ""]
565 - !If [ShouldEnableGitSSH,!Sub "echo \"gitlab_rails['gitlab_ssh_host']='${GitlabSSHNetworkLoadBalancer.DNSName}'\"", ""]
566 /root/gitlabapp-user-data.sh:
567 source: !Sub 'https://s3-${AWS::Region}.amazonaws.com/${QSS3BucketName}/scripts/gitlabapp-user-data.sh'
568 mode: 777
569 owner: root
570 group: root
571 authentication: S3AccessCreds
572 /root/gitlabapp-finish-init.sh:
573 source: !Sub 'https://s3-${AWS::Region}.amazonaws.com/${QSS3BucketName}/scripts/gitlabapp-finish-init.sh'
574 mode: 777
575 owner: root
576 group: root
577 authentication: S3AccessCreds
578 commands:
579 10-installation:
580 command: !Sub 'bash /root/gitlabapp-user-data.sh --region ${AWS::Region} --gitlab-volume ${GitLabVolume} --stack-name ${AWS::StackName} --qss3-bucket-name ${QSS3BucketName} --qss3-key-prefix ${QSS3KeyPrefix}'
581 20-append-config:
582 command: cat /etc/gitlab/gitlab-init.rb > /etc/gitlab/gitlab.rb
583 30-enter-urls:
584 command: bash /etc/gitlab/gitlab-urls.sh >> /etc/gitlab/gitlab.rb
585 40-gitlab-start:
586 command: gitlab-ctl reconfigure
587 50-ask-for-token:
588 command: !If
589 - GitLabEnterpriseCondition
590 - !Sub 'curl -X POST http://localhost/oauth/token -d "grant_type=password&username=root&password=${GitLabPassword}"
591 > /home/ubuntu/access_token_json'
592 - echo "community edition"
593 60-extract-token:
594 command: !If
595 - GitLabEnterpriseCondition
596 - python -c "import json; print json.load(open('/home/ubuntu/access_token_json',
597 'r'))['access_token']" > /home/ubuntu/access_token
598 - echo "community edition"
599 70-setup-elasticsearch:
600 command: !If
601 - GitLabEnterpriseCondition
602 - !Sub 'curl -X PUT http://localhost/api/v4/application/settings -H
603 "Content-Type: application/x-www-form-urlencoded" -H "Authorization:
604 Bearer `cat /home/ubuntu/access_token`" -d "elasticsearch_indexing=true&elasticsearch_url=${ElasticsearchEndpoint}&elasticsearch_search=true&gravatar_enabled=true"'
605 - echo "community edition"
606 80-restart-cron:
607 command: systemctl restart cron
608 90-execution-backup:
609 command: chmod +x /etc/gitlab/*.sh
610 99-finish-init:
611 command: !Sub 'bash -x /root/gitlabapp-finish-init.sh --region ${AWS::Region} --stack-name ${AWS::StackName} --qss3-bucket-name ${QSS3BucketName} --qss3-key-prefix ${QSS3KeyPrefix}'
612
613 Properties:
614 KeyName: !Ref 'KeyName'
615 ImageId: !Ref 'GitLabCommunityAMI'
616 SpotPrice: !If
617 - ShouldHaveSpotInstance
618 - !Ref 'GitLabSpotPrice'
619 - !Ref 'AWS::NoValue'
620 SecurityGroups:
621 - !Ref 'InstanceSecurityGroup'
622 InstanceType: !Ref 'InstanceType'
623 BlockDeviceMappings:
624 - DeviceName: /dev/sda1
625 Ebs:
626 VolumeSize: !Ref 'InstanceStorageSize'
627 VolumeType: !Ref 'InstanceStorageType'
628 Iops: !If
629 - GitLabStorageWithIOPSCondition
630 - !Ref 'InstanceStorageIOPS'
631 - !Ref 'AWS::NoValue'
632 IamInstanceProfile: !Ref 'InstanceProfileName'
633 UserData: !Base64
634 Fn::Join:
635 - "\n"
636 - - '#!/bin/bash'
637 - set -x -e
638 - until apt-get update; do sleep 10; done
639 - until apt-get -y install python-setuptools apt-transport-https ca-certificates; do sleep 10; done
640 - until easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz; do sleep 10; done
641 - !Sub "cfn-init --stack ${AWS::StackName} --resource WebServerLaunchConfiguration
642 --region ${AWS::Region} -v"
643
644 InstanceSecurityGroup:
645 Type: AWS::EC2::SecurityGroup
646 Properties:
647 VpcId: !Ref 'VpcId'
648 GroupDescription: Enable SSH access from Bastion via port 22, and from ELB via
649 port range 80-65535
650 SecurityGroupIngress:
651 - IpProtocol: tcp
652 FromPort: '22'
653 ToPort: '22'
654 CidrIp: !If [ShouldEnableGitSSH, '0.0.0.0/0', !Ref 'VPCCIDR']
655 - IpProtocol: tcp
656 FromPort: '80'
657 ToPort: '65535'
658 SourceSecurityGroupId: !Ref 'GitlabELBSecurityGroup'
659 GitlabSSHNetworkLoadBalancer:
660 Condition: ShouldEnableGitSSH
661 Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
662 Properties:
663 Type: network
664 Scheme: !If [ShouldEnableVPN, 'internal', 'internet-facing']
665 Subnets:
666 - !Ref 'PublicSubnet1ID'
667 - !Ref 'PublicSubnet2ID'
668 GitlabSSHNLBTargetGroup:
669 Condition: ShouldEnableGitSSH
670 Type: AWS::ElasticLoadBalancingV2::TargetGroup
671 Properties:
672 HealthCheckIntervalSeconds: 10
673 HealthCheckProtocol: TCP
674 Port: 22
675 Protocol: TCP
676 VpcId: !Ref 'VpcId'
677 GitlabSSHNLBListener:
678 Condition: ShouldEnableGitSSH
679 Type : AWS::ElasticLoadBalancingV2::Listener
680 Properties:
681 DefaultActions:
682 -
683 Type: forward
684 TargetGroupArn: !Ref GitlabSSHNLBTargetGroup
685 LoadBalancerArn: !Ref GitlabSSHNetworkLoadBalancer
686 Port: 22
687 Protocol: TCP
688
689 GitlabElasticInternalLoadBalancerTargetGroup:
690 Type: AWS::ElasticLoadBalancingV2::TargetGroup
691 Properties:
692 Port: 80
693 Protocol: HTTP
694 HealthCheckIntervalSeconds: 10
695 HealthCheckProtocol: HTTP
696 HealthCheckTimeoutSeconds: 5
697 HealthyThresholdCount: 2
698 Matcher:
699 HttpCode: '302'
700 VpcId: !Ref VpcId
701
702 GitlabElasticInternalApplicationLoadBalancer:
703 Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
704 Properties:
705 Type: application
706 Scheme: 'internal'
707 SecurityGroups:
708 - !Ref 'GitlabELBSecurityGroup'
709 Subnets:
710 - !Ref 'PrivateSubnet1ID'
711 - !Ref 'PrivateSubnet2ID'
712
713 GitlabElasticInternalLoadBalancerHTTPSListener:
714 Condition: ShouldEnableHttps
715 Type : AWS::ElasticLoadBalancingV2::Listener
716 Properties:
717 DefaultActions:
718 -
719 Type: forward
720 TargetGroupArn: !Ref GitlabElasticInternalLoadBalancerTargetGroup
721 LoadBalancerArn: !Ref GitlabElasticInternalApplicationLoadBalancer
722 Certificates:
723 - CertificateArn: !Ref SSLCertificateArn
724 Port: 443
725 Protocol: HTTPS
726
727 GitlabElasticInternalLoadBalancerHTTPListener:
728 Type : AWS::ElasticLoadBalancingV2::Listener
729 Properties:
730 DefaultActions:
731 -
732 Type: forward
733 TargetGroupArn: !Ref GitlabElasticInternalLoadBalancerTargetGroup
734 LoadBalancerArn: !Ref GitlabElasticInternalApplicationLoadBalancer
735 Port: 80
736 Protocol: HTTP
737
738 GitlabElasticApplicationLoadBalancer:
739 Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
740 Properties:
741 Type: application
742 Scheme: !If [ShouldEnableVPN, 'internal', 'internet-facing']
743 SecurityGroups:
744 - !Ref 'GitlabELBSecurityGroup'
745 Subnets:
746 - !Ref 'PublicSubnet1ID'
747 - !Ref 'PublicSubnet2ID'
748
749 GitlabElasticLoadBalancerTargetGroup:
750 Type: AWS::ElasticLoadBalancingV2::TargetGroup
751 Properties:
752 Port: 80
753 Protocol: HTTP
754 HealthCheckIntervalSeconds: 10
755 HealthCheckProtocol: HTTP
756 HealthCheckTimeoutSeconds: 5
757 HealthyThresholdCount: 2
758 Matcher:
759 HttpCode: '302'
760 VpcId: !Ref VpcId
761
762 GitlabElasticLoadBalancerHTTPListener:
763 Type : AWS::ElasticLoadBalancingV2::Listener
764 Properties:
765 DefaultActions:
766 -
767 Type: forward
768 TargetGroupArn: !Ref GitlabElasticLoadBalancerTargetGroup
769 LoadBalancerArn: !Ref GitlabElasticApplicationLoadBalancer
770 Port: 80
771 Protocol: HTTP
772 GitlabElasticLoadBalancerHTTPSListener:
773 Condition: ShouldEnableHttps
774 Type : AWS::ElasticLoadBalancingV2::Listener
775 Properties:
776 DefaultActions:
777 -
778 Type: forward
779 TargetGroupArn: !Ref GitlabElasticLoadBalancerTargetGroup
780 LoadBalancerArn: !Ref GitlabElasticApplicationLoadBalancer
781 Certificates:
782 - CertificateArn: !Ref SSLCertificateArn
783 Port: 443
784 Protocol: HTTPS
785
786 GitlabELBSecurityGroup:
787 Type: AWS::EC2::SecurityGroup
788 Properties:
789 VpcId: !Ref 'VpcId'
790 GroupDescription: Enable Elastic Load Balancer access via port 80
791 SecurityGroupIngress:
792 - IpProtocol: tcp
793 FromPort: '80'
794 ToPort: '80'
795 CidrIp: '0.0.0.0/0'
796 - !If [ShouldEnableHttps, { IpProtocol: 'tcp', FromPort: '443', ToPort: '443', CidrIp: '0.0.0.0/0' }, !Ref "AWS::NoValue" ]
797 GitLabVolume:
798 Type: AWS::EC2::Volume
799 Properties:
800 AvailabilityZone: !Ref 'AvailabilityZone'
801 Encrypted: 'true'
802 KmsKeyId: !Ref 'KMSKeyId'
803 Size: !Ref 'GitLabDataStorageSize'
804 VolumeType: !Ref 'GitLabDataStorageType'
805 Iops: !If
806 - GitLabDataStorageWithIOPSCondition
807 - !Ref 'GitLabDataStorageIOPS'
808 - !Ref 'AWS::NoValue'
809 Tags:
810 - Key: Name
811 Value: GitLabData
812 DeletionPolicy: Retain
813Outputs:
814 # GitlabLoadBalancerListenerARN:
815 # Value: !Ref GitlabElasticLoadBalancerHTTPSListener
816 # GitlabInternalLoadBalancerListenerARN:
817 # Value: !Ref GitlabElasticInternalLoadBalancerHTTPSListener
818 GitlabElasticInternalLoadBalancerEndpoint:
819 Value: !GetAtt 'GitlabElasticInternalApplicationLoadBalancer.DNSName'
820 Description: GitLab Internal Elastic Load Balancer URL
821 GitlabElasticInternalLoadBalancerHostedZoneID:
822 Value: !GetAtt 'GitlabElasticInternalApplicationLoadBalancer.CanonicalHostedZoneID'
823 Description: HostedZoneID for GitLab Internal ELB
824 GitlabElasticLoadBalancerEndpoint:
825 Value: !GetAtt 'GitlabElasticApplicationLoadBalancer.DNSName'
826 Description: GitLab Elastic Load Balancer URL
827 GitlabElasticLoadBalancerHostedZoneID:
828 Value: !GetAtt 'GitlabElasticApplicationLoadBalancer.CanonicalHostedZoneID'
829 Description: HostedZoneID for GitLab ELB
830 GitlabSSHEndpoint:
831 Value: !If [ShouldEnableGitSSH, !GetAtt 'GitlabSSHNetworkLoadBalancer.DNSName', '<None>']
832 Description: GitLab SSH Network Load Balancer URL
833 GitlabSSHHostedZoneID:
834 Value: !If [ShouldEnableGitSSH, !GetAtt 'GitlabSSHNetworkLoadBalancer.CanonicalHostedZoneID', '<None>']
835 Description: GitLab SSH Network Load Balancer HostedZoneID
836 BackupDocumentCommand:
837 Value: !Ref GitLabBackupSSMCommand
838 RestoreDocumentCommand:
839 Value: !Ref GitLabRestoreSSMCommand
840 TokenSSMAPI:
841 Value: !GetAtt GitLabAPIToken.Secret