Pre-existing initial_root_password in /etc/gitlab/gitlab.rb causes cloud-init to fail
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Summary
We are running Gitlab using the official AWS AMI on EC2. Using a value for initial_root_password in /etc/gitlab/gitlab.rb causes the Gitlab-provided per-instance/gitlab script for cloud-init to fail during gitlab-ctl reconfigure, leaving a newly provisioned instance unconfigured and requiring manual intervention.
Steps to reproduce
- Ensure that
/etc/gitlab/gitlab.rbis present and contains a setting forinitial_root_password. - Manually run
/var/lib/cloud/scripts/per-instance/gitlab. In my testing, the behavior was reproducible at any point if the setting was present ingitlab.rb.
Example Project
n/a
What is the current bug behavior?
I order to avoid embedding secrets in userdata, we template /etc/gitlab/gitlab.rb with values from SSM Parameter Store. Among these values is initial_root_password. This works correctly, and the setting is pre-filled with an alnum-only 32 character string. After starting up, a manual gitlab-ctl reconfigure works correctly, as does the password login.
However, the script /var/lib/cloud/scripts/per-instance/gitlab contains the following:
EXISTING_ROOT_PASSWORD=$(sudo grep "^gitlab_rails.*initial_root_password.*" /etc/gitlab/gitlab.rb | cut -d '=' -f2- | xargs)
if [ -z "${EXISTING_ROOT_PASSWORD}" ] && [ -z "${GITLAB_ROOT_PASSWORD}" ]; then
GITLAB_ROOT_PASSWORD=$(curl http://169.254.169.254/latest/meta-data/instance-id)
fi
sudo GITLAB_ROOT_PASSWORD=${GITLAB_ROOT_PASSWORD} gitlab-ctl reconfigure
This contains a logic error: If EXISTING_ROOT_PASSWORD is set, GITLAB_ROOT_PASSWORD is set to an empty string. In /opt/gitlab/embedded/cookbooks/cache/cookbooks/gitlab/libraries/gitlab_rails.rb, the root password is validated as such:
# Environment variable gets priority over gitlab.rb setting
Gitlab['gitlab_rails']['initial_root_password'] = ENV['GITLAB_ROOT_PASSWORD'] || Gitlab['gitlab_rails']['initial_root_password']
[...]
raise 'initial_root_password: Length is too short, minimum is 8 characters' if Gitlab['gitlab_rails']['initial_root_password'] && Gitlab['gitlab_rails']['initial_root_password'].length < 8
Since GITLAB_ROOT_PASSWORD is an empty string and not nil or false, it takes precedence over the setting in gitlab.rb. This results in the following error:
Running handlers:
[2024-01-05T11:27:53+00:00] ERROR: Running exception handlers
There was an error running gitlab-ctl reconfigure:
initial_root_password: Length is too short, minimum is 8 characters
What is the expected correct behavior?
If provided in gitlab.rb, the user-defined password should be used.
Relevant logs and/or screenshots
No further logs needed, I think.
Output of checks
Results of GitLab environment info
Expand for output related to GitLab environment info
System information System: Ubuntu 20.04 Current User: git Using RVM: no Ruby Version: 3.1.4p223 Gem Version: 3.4.22 Bundler Version:2.4.22 Rake Version: 13.0.6 Redis Version: 7.0.14 Sidekiq Version:6.5.12 Go Version: unknown GitLab information Version: 16.7.0 Revision: 0fb7483d0df Directory: /opt/gitlab/embedded/service/gitlab-rails DB Adapter: PostgreSQL DB Version: 13.12 URL: https://git.redacted.com HTTP Clone URL: https://git.redacted.com/some-group/some-project.git SSH Clone URL: git@git.redacted.com:some-group/some-project.git Using LDAP: no Using Omniauth: yes Omniauth Providers: GitLab Shell Version: 14.32.0 Repository storages: - default: unix:/var/opt/gitlab/gitaly/gitaly.socket GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell Gitaly - default Address: unix:/var/opt/gitlab/gitaly/gitaly.socket - default Version: 16.7.0 - default Git Version: 2.42.0
Results of GitLab application Check
Expand for output related to the GitLab application check
Checking GitLab subtasks ...
Checking GitLab Shell ...
GitLab Shell: ... GitLab Shell version >= 14.32.0 ? ... OK (14.32.0) Running /opt/gitlab/embedded/service/gitlab-shell/bin/check Internal API available: OK Redis available via internal API: OK gitlab-shell self-check successful
Checking GitLab Shell ... Finished
Checking Gitaly ...
Gitaly: ... default ... OK
Checking Gitaly ... Finished
Checking Sidekiq ...
Sidekiq: ... Running? ... yes Number of Sidekiq processes (cluster/worker) ... 1/1
Checking Sidekiq ... Finished
Checking Incoming Email ...
Incoming Email: ... Reply by email is disabled in config/gitlab.yml
Checking Incoming Email ... Finished
Checking LDAP ...
LDAP: ... LDAP is disabled in config/gitlab.yml
Checking LDAP ... Finished
Checking GitLab App ...
Database config exists? ... yes Tables are truncated? ... skipped All migrations up? ... yes Database contains orphaned GroupMembers? ... no GitLab config exists? ... yes GitLab config up to date? ... yes Cable config exists? ... yes Resque config exists? ... yes Log directory writable? ... yes Tmp directory writable? ... yes Uploads directory exists? ... yes Uploads directory has correct permissions? ... yes Uploads directory tmp has correct permissions? ... yes Systemd unit files or init script exist? ... skipped (omnibus-gitlab has neither init script nor systemd units) Systemd unit files or init script up-to-date? ... skipped (omnibus-gitlab has neither init script nor systemd units) Projects have namespace: ... 2/1 ... yes 1/2 ... yes 8/3 ... yes 11/4 ... yes 11/6 ... yes 13/7 ... yes 13/8 ... yes 13/9 ... yes 13/10 ... yes 13/11 ... yes 13/12 ... yes 13/13 ... yes 13/14 ... yes 13/15 ... yes 20/16 ... yes 13/17 ... yes 14/18 ... yes 33/19 ... yes 13/20 ... yes 14/21 ... yes 23/22 ... yes 21/23 ... yes 21/24 ... yes 14/25 ... yes 21/26 ... yes 18/27 ... yes 8/28 ... yes 13/32 ... yes 33/33 ... yes 8/34 ... yes 14/35 ... yes 33/36 ... yes 33/37 ... yes 33/38 ... yes 14/40 ... yes 33/41 ... yes 33/42 ... yes 18/43 ... yes 20/44 ... yes 31/45 ... yes 14/46 ... yes 33/47 ... yes 33/48 ... yes 14/49 ... yes 14/50 ... yes 31/51 ... yes 89/52 ... yes 33/53 ... yes 89/54 ... yes 18/55 ... yes 31/56 ... yes 33/57 ... yes 33/58 ... yes 33/59 ... yes 104/61 ... yes 104/62 ... yes 104/63 ... yes 116/66 ... yes 116/70 ... yes 14/71 ... yes 13/72 ... yes 104/73 ... yes 104/74 ... yes 113/75 ... yes 14/76 ... yes 104/77 ... yes 33/78 ... yes 104/79 ... yes 104/80 ... yes 104/81 ... yes 104/82 ... yes 104/83 ... yes 142/84 ... yes 142/85 ... yes 148/86 ... yes 148/87 ... yes 116/88 ... yes 14/89 ... yes 159/90 ... yes 104/91 ... yes 116/92 ... yes 104/93 ... yes 104/94 ... yes 104/95 ... yes 33/96 ... yes 104/97 ... yes 142/98 ... yes 148/99 ... yes 13/100 ... yes 139/101 ... yes 142/104 ... yes 8/105 ... yes 8/106 ... yes 14/107 ... yes 33/108 ... yes 14/109 ... yes 20/110 ... yes 20/111 ... yes 8/113 ... yes 8/114 ... yes 8/115 ... yes 104/116 ... yes 159/120 ... yes 23/121 ... yes 142/124 ... yes 14/125 ... yes 180/128 ... yes 14/129 ... yes 231/130 ... yes 23/131 ... yes 14/132 ... yes 14/133 ... yes 8/134 ... yes 104/135 ... yes 180/136 ... yes 243/137 ... yes 8/138 ... yes 245/139 ... yes 18/140 ... yes 18/141 ... yes 8/142 ... yes 33/143 ... yes 142/144 ... yes 8/145 ... yes 14/146 ... yes 14/147 ... yes 266/148 ... yes 142/149 ... yes 13/150 ... yes 20/151 ... yes 273/153 ... yes Redis version >= 6.0.0? ... yes Ruby version >= 3.0.6 ? ... yes (3.1.4) Git user has default SSH configuration? ... yes Active users: ... 65 Is authorized keys file accessible? ... yes GitLab configured to store new projects in hashed storage? ... yes All projects are in hashed storage? ... yes
Checking GitLab App ... Finished
Checking GitLab subtasks ... Finished
Possible fixes
Either change the evaluation here to disallow empty strings for the env or set the env to EXISTING_ROOT_PASSWORD like so:
EXISTING_ROOT_PASSWORD=$(sudo grep "^gitlab_rails.*initial_root_password.*" /etc/gitlab/gitlab.rb | cut -d '=' -f2- | xargs)
if [ -z "${EXISTING_ROOT_PASSWORD}" ] && [ -z "${GITLAB_ROOT_PASSWORD}" ]; then
GITLAB_ROOT_PASSWORD=$(curl http://169.254.169.254/latest/meta-data/instance-id)
else
GITLAB_ROOT_PASSWORD="${GITLAB_ROOT_PASSWORD:-${EXISTING_ROOT_PASSWORD}}"
fi
(This is a sample fix - depending on what your actual intended outcome priorities are, this may not do what you want.)