The KnowledgeBase Blog
CICD

Когда Terraform просит логин у GitLab: разбираемся с токенами и сохранением доступа

10 Jul 2026 11 min read ci/cdgitlab

Частый сценарий: инфраструктура описана в Terraform, а переиспользуемые модули лежат в приватном репозитории GitLab.

В конфигурации Terraform указываем HTTPS адрес репозитория:

module "infrastructure" {
  source = "git::https://gitlab.example.com/admins/terraform/terraform-code.git?ref=master"
}

После этого запускаем:

terraform init

И вместо автоматического скачивания модуля получаем запрос:

Username for 'https://gitlab.example.com':
Password for 'https://gitlab.example.com':

Обычно это означает одно из следующего:

  • старый токен GitLab истёк;
  • токен был отозван;
  • у токена недостаточно прав;
  • Git продолжает использовать старый сохранённый токен;
  • на машине вообще не настроено сохранение учётных данных.

Разберёмся, почему Terraform просит логин и пароль, как создать новый токен и как сделать так, чтобы доступ к GitLab работал стабильно.

Почему Terraform вообще спрашивает логин

Terraform не реализует отдельный механизм авторизации для GitLab.

Когда в source используется Git репозиторий:

source = "git::https://gitlab.example.com/admins/terraform/terraform-code.git?ref=master"

Terraform внутри вызывает обычный Git и загружает репозиторий примерно так же, как если бы мы выполнили:

git clone https://gitlab.example.com/admins/terraform/terraform-code.git

Поэтому всё, что связано с авторизацией, определяется настройками Git на текущей машине:

  • сохранёнными логинами и токенами;
  • настройками credential.helper;
  • системным хранилищем паролей;
  • SSH ключами;
  • переменными окружения;
  • конфигурацией пользователя, от которого запускается Terraform.

Если обычный git clone не может получить доступ к репозиторию, Terraform тоже не сможет скачать модуль.

Что такое Personal Access Token в GitLab

Для доступа к приватным репозиториям GitLab по HTTPS вместо пароля аккаунта используется Personal Access Token, сокращённо PAT.

Это длинная строка, которая:

  • привязана к конкретному пользователю GitLab;
  • имеет ограниченный набор прав;
  • имеет срок действия;
  • может быть отозвана без смены пароля пользователя.

Для чтения приватного репозитория Terraform обычно достаточно права:

read_repository

Такой токен позволяет выполнять операции чтения:

git clone
git fetch
git pull
git ls-remote

При этом токен не выдаёт пользователю доступ к новым проектам. Пользователь, которому принадлежит PAT, уже должен иметь право читать нужный репозиторий.

Как создать новый Personal Access Token:

Зайдите в веб интерфейс GitLab под своим аккаунтом.

Откройте раздел управления токенами. В зависимости от версии GitLab путь может называться немного по-разному:

Edit profile → Access → Personal access tokens

или:

Preferences → Access Tokens

или:

User Settings → Access Tokens

При создании токена укажите:

  • Name - понятное имя, например terraform-readonly;
  • Expiration date - дату окончания действия;
  • Scopes - как минимум read_repository.

После этого нажмите:

Create personal access token

GitLab покажет значение токена только один раз.

Сразу скопируйте его и сохраните в надёжное место. Позже посмотреть этот же токен повторно не получится - при потере придётся создавать новый.

Не выдавайте токену лишние права. Если Terraform должен только скачивать модули, ему не нужны:

api
write_repository
sudo
admin_mode

Чем меньше прав у токена, тем меньше последствий будет при его утечке.

Как проверить токен без Terraform

Перед повторным запуском Terraform лучше проверить доступ обычной командой Git.

Можно выполнить полное клонирование:

git clone https://gitlab.example.com/admins/terraform/terraform-code.git

Но для проверки авторизации достаточно более лёгкой команды:

git ls-remote https://gitlab.example.com/admins/terraform/terraform-code.git

Git запросит логин:

Username for 'https://gitlab.example.com':

Вводим свой логин GitLab.

Затем появится запрос:

Password for 'https://username@gitlab.example.com':

Сюда вставляем Personal Access Token, а не пароль от аккаунта.

Для Git токен выглядит как обычный пароль, но GitLab использует его как отдельный механизм авторизации.

Во время вставки токена терминал обычно ничего не показывает: ни символы, ни звёздочки. Это нормально. Просто вставляем токен и нажимаем Enter.

Если авторизация прошла успешно, команда вернёт список веток и тегов:

6d8f97d81c8e1c5e1b73e30c26083f1d8c84e7ef    HEAD
6d8f97d81c8e1c5e1b73e30c26083f1d8c84e7ef    refs/heads/master
7fc4baf8f7c86f6e390c8e46eb248abf4af5b806    refs/tags/v1.2.0

Это означает, что:

  • адрес репозитория указан правильно;
  • GitLab доступен по сети;
  • токен работает;
  • у пользователя есть доступ к проекту;
  • scope read_repository настроен правильно.

После этого можно снова запускать:

terraform init

Сохранится ли токен автоматически

Токен сохранится только в том случае, если у Git настроен credential helper.

Credential helper - это механизм, через который Git получает и сохраняет логины и токены.

В зависимости от операционной системы credentials могут храниться:

  • в macOS Keychain;
  • в Windows Credential Manager;
  • в Linux Secret Service или другом менеджере секретов;
  • в оперативной памяти;
  • в обычном текстовом файле.

Проверить текущую настройку можно командой:

git config --show-origin --get-all credential.helper

Например, результат может выглядеть так:

file:/home/user/.gitconfig    store

или:

file:C:/Program Files/Git/etc/gitconfig    manager

или:

file:/Users/user/.gitconfig    osxkeychain

Если команда ничего не выводит, значит credential helper, скорее всего, не настроен.

Можно также выполнить более простую проверку:

git config --global credential.helper

Но эта команда показывает только глобальную пользовательскую настройку. Helper также может быть настроен на системном или локальном уровне, поэтому вариант с --show-origin --get-all информативнее.

Настройка credential helper на macOS

На macOS Git может хранить credentials в системном Keychain.

Для включения helper выполните:

git config --global credential.helper osxkeychain

После этого снова проверьте доступ:

git ls-remote https://gitlab.example.com/admins/terraform/terraform-code.git

Git один раз попросит логин и токен, после чего сохранит их в Keychain.

Следующие команды уже не должны запрашивать пароль:

git fetch
git pull
terraform init

Если osxkeychain уже настроен на системном уровне, повторно добавлять его в глобальную конфигурацию не обязательно.

Настройка credential helper на Linux

На Linux есть несколько вариантов.

Хранение в системном менеджере секретов:

Если установлен helper libsecret, можно использовать его:

git config --global credential.helper libsecret

В этом случае токен будет храниться через системный Secret Service, а не в обычном текстовом файле.

Доступность helper можно проверить командой:

git help -a | grep credential-

В зависимости от дистрибутива и способа установки Git имя доступной команды может отличаться.

Временное хранение в памяти:

Можно настроить временный кэш:

git config --global credential.helper 'cache --timeout=3600'

Здесь 3600 - время хранения credentials в секундах.

Git запомнит токен примерно на один час, после чего снова начнёт его запрашивать.

Такой вариант удобен, если не хочется сохранять токен на диск.

Хранение в обычном файле:

Самый простой вариант:

git config --global credential.helper store

После первого ввода логина и токена Git сохранит их, как правило, в файле:

~/.git-credentials

Содержимое может выглядеть примерно так:

https://username:token@gitlab.example.com

Важно понимать: токен хранится в незашифрованном виде.

Поэтому store подходит только для локальной машины, если вы понимаете связанные с этим риски.

Для общих серверов, production систем и CI/CD такой способ использовать не стоит.

Что делать, если Git продолжает использовать старый токен

Иногда новый PAT уже создан, но Git всё равно возвращает ошибку:

HTTP Basic: Access denied

Причина может быть в том, что credential helper продолжает подставлять старый сохранённый токен.

В этом случае старые credentials необходимо удалить.

Универсальный вариант:

printf 'protocol=https\nhost=gitlab.example.com\nusername=username\n\n' \
  | git credential reject

Замените:

gitlab.example.com

на адрес своего GitLab, а:

username

на свой логин.

После этого снова выполните:

git ls-remote https://gitlab.example.com/admins/terraform/terraform-code.git

Git должен заново запросить логин и пароль. В поле пароля вставляем новый PAT.

Также credentials можно удалить вручную.

На macOS:

Keychain Access

На Windows:

Credential Manager

На Linux - через используемый системный keyring или менеджер секретов.

Если используется credential.helper store, откройте:

~/.git-credentials

и удалите строку со старым токеном.

Почему новый токен может не работать

Если новый токен создан, но GitLab всё равно отклоняет доступ, проверьте несколько вещей.

У токена отсутствует read_repository:

Для клонирования приватного репозитория должен быть включён scope:

read_repository

Без него токен может существовать, но не иметь права читать Git репозиторий.

Пользователь не имеет доступа к проекту:

PAT наследует права своего пользователя.

Если пользователя удалили из проекта или группы, токен не сможет читать репозиторий, даже если у него включён read_repository.

Токен истёк:

Проверьте дату окончания действия PAT в GitLab.

После истечения срока токен перестаёт работать, а сохранённая запись в credential helper автоматически не обновляется.

спользуется старый токен:

Git может брать старый PAT из:

  • Keychain;
  • Windows Credential Manager;
  • ~/.git-credentials;
  • системного keyring;
  • переменной окружения;
  • скрипта;
  • CI/CD variable.

Поэтому после ротации токена важно удалить или обновить старое значение во всех местах, где оно могло быть сохранено.

Указан неправильный адрес репозитория:

Скопируйте HTTPS URL непосредственно из GitLab:

Code → Clone with HTTPS

Проверьте:

  • имя GitLab сервера;
  • namespace;
  • название проекта;
  • наличие .git;
  • регистр символов;
  • доступ пользователя к проекту.

Возвращаемся к Terraform

После того как команда:

git ls-remote https://gitlab.example.com/admins/terraform/terraform-code.git

отрабатывает успешно, запускаем:

terraform init

Если модуль уже был загружен, но нужно проверить обновления, можно использовать:

terraform init -upgrade

Для простой замены токена удалять каталог .terraform обычно не требуется.

Terraform при следующем обращении к Git использует актуальные credentials из настроенного helper.

Лучше фиксировать версию модуля

В примере используется ветка:

source = "git::https://gitlab.example.com/admins/terraform/terraform-code.git?ref=master"

Такой вариант работает, но ветка master может измениться в любой момент.

В результате одна и та же конфигурация Terraform сегодня и через неделю может скачать разные версии модуля.

Для более предсказуемой работы лучше использовать тег:

module "infrastructure" {
  source = "git::https://gitlab.example.com/admins/terraform/terraform-code.git?ref=v1.2.0"
}

Или конкретный commit SHA:

module "infrastructure" {
  source = "git::https://gitlab.example.com/admins/terraform/terraform-code.git?ref=6d8f97d81c8e1c5e1b73e30c26083f1d8c84e7ef"
}

Тег удобнее для обычного версионирования, а commit SHA даёт максимально строгую фиксацию исходного кода.

Если модуль лежит в подкаталоге

Если Terraform-модуль находится не в корне Git-репозитория, а внутри каталога, путь указывается после двойного слеша:

module "network" {
  source = "git::https://gitlab.example.com/admins/terraform/terraform-code.git//modules/network?ref=v1.2.0"
}

Здесь:

https://gitlab.example.com/admins/terraform/terraform-code.git

- адрес репозитория,

а:

//modules/network

- путь к модулю внутри репозитория.

Если модуль лежит в корне, двойной слеш добавлять не нужно:

module "infrastructure" {
  source = "git::https://gitlab.example.com/admins/terraform/terraform-code.git?ref=v1.2.0"
}

Не вставляйте токен прямо в `source`

Технически можно записать токен непосредственно в HTTPS URL:

module "infrastructure" {
  source = "git::https://username:token@gitlab.example.com/admins/terraform/terraform-code.git?ref=v1.2.0"
}

Но так делать не стоит.

Токен может попасть:

  • в Git-репозиторий с Terraform-кодом;
  • в историю коммитов;
  • в логи Terraform;
  • в логи CI/CD;
  • в историю команд;
  • в резервную копию проекта;
  • в вывод диагностических инструментов.

Даже если позже удалить токен из файла, он может остаться в истории Git.

Для локальной работы используйте credential helper.

Для CI/CD используйте защищённые переменные, deploy token, project access token или другой подходящий механизм.

Альтернатива HTTPS - SSH-ключи

Можно полностью отказаться от HTTPS токенов и настроить доступ по SSH.

Для этого:

  1. Создаём SSH-ключ.
  2. Добавляем публичную часть ключа в GitLab.
  3. Проверяем подключение.
  4. Меняем адрес модуля в Terraform.

Создать ключ можно командой:

ssh-keygen -t ed25519 -C "terraform@gitlab"

Публичный ключ обычно находится здесь:

~/.ssh/id_ed25519.pub

Его содержимое нужно добавить в GitLab:

Edit profile → Access → SSH keys

Проверяем подключение:

ssh -T git@gitlab.example.com

Проверяем доступ к репозиторию:

git ls-remote git@gitlab.example.com:admins/terraform/terraform-code.git

После этого меняем source:

module "infrastructure" {
  source = "git::ssh://git@gitlab.example.com/admins/terraform/terraform-code.git?ref=v1.2.0"
}

Если модуль лежит в подкаталоге:

module "network" {
  source = "git::ssh://git@gitlab.example.com/admins/terraform/terraform-code.git//modules/network?ref=v1.2.0"
}

Теперь авторизация будет выполняться через SSH ключ, а Personal Access Token для загрузки модулей больше не понадобится.

При этом закрытый SSH ключ тоже является секретом. Его нужно защищать, не добавлять в репозиторий и по возможности использовать вместе с passphrase и ssh-agent.

Что использовать в CI/CD

Для локальной машины Personal Access Token подходит нормально.

Для CI/CD лучше не использовать личный PAT сотрудника, потому что такой токен зависит от его аккаунта:

  • пользователь может уволиться;
  • аккаунт могут заблокировать;
  • пользователя могут удалить из группы;
  • токен может истечь;
  • права пользователя могут измениться.

В GitLab CI/CD лучше использовать один из специальных механизмов.

CI_JOB_TOKEN:

GitLab автоматически создаёт переменную:

CI_JOB_TOKEN

Токен существует только во время выполнения job.

Для доступа к репозиторию обычно используется username:

gitlab-ci-token

Пример настройки Git:

git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/".insteadOf "https://gitlab.example.com/"

После этого Terraform сможет загружать HTTPS модули с того же GitLab:

terraform init

При доступе к другому приватному проекту может потребоваться разрешить исходному проекту использование job token в настройках целевого проекта.

Deploy Token:

Deploy Token не привязан к личному аккаунту пользователя.

Для чтения репозитория ему достаточно scope:

read_repository

Такой вариант подходит для внешней автоматизации, серверов сборки и систем развёртывания.

Project Access Token:

Project Access Token создаётся на уровне конкретного проекта.

Он удобен, когда автоматизации нужен отдельный технический доступ, не связанный с аккаунтом сотрудника.

Для загрузки репозитория достаточно:

read_repository

Deploy Key:

Deploy Key позволяет предоставить серверу SSH-доступ к репозиторию.

Для Terraform-модулей обычно достаточно ключа только для чтения.

Это хороший вариант для CI runner или отдельного сервера автоматизации.

Типовые ошибки

HTTP Basic: Access denied:

Обычно означает одно из следующего:

  • токен указан неправильно;
  • токен истёк;
  • токен отозван;
  • отсутствует read_repository;
  • пользователь потерял доступ к проекту;
  • Git подставляет старый сохранённый токен.

Сначала удалите старые credentials, затем проверьте доступ через:

git ls-remote https://gitlab.example.com/admins/terraform/terraform-code.git

repository not found:

Возможные причины:

  • неправильный URL;
  • проект был переименован или перенесён;
  • пользователь не имеет доступа;
  • используется токен другого пользователя;
  • репозиторий находится в другой группе.

Скопируйте HTTPS URL непосредственно из интерфейса GitLab.

could not resolve host:

Это уже не ошибка токена.

Проверьте:

  • DNS;
  • VPN;
  • proxy;
  • адрес GitLab;
  • доступность сервера из текущей сети.

Ошибка TLS-сертификата:

Например:

SSL certificate problem: unable to get local issuer certificate

Обычно это означает, что на машине отсутствует доверенный корневой сертификат внутреннего GitLab.

Правильное решение - установить корпоративный CA сертификат в системное хранилище доверенных сертификатов.

Не стоит отключать проверку TLS командой:

git config --global http.sslVerify false

Такая настройка снижает безопасность всех HTTPS подключений Git.

Git работает вручную, а Terraform продолжает спрашивать пароль:

Проверьте, от какого пользователя запускается Terraform.

Например:

whoami

Также проверьте:

echo "$HOME"
which git
git config --show-origin --get-all credential.helper

Terraform может запускаться:

  • через sudo;
  • внутри контейнера;
  • от другого системного пользователя;
  • через IDE;
  • через CI runner;
  • с другим значением HOME.

В этом случае он использует другую конфигурацию Git и не видит credentials вашего пользователя.

Что важно помнить

Terraform не хранит GitLab токены самостоятельно.

Он использует обычный Git и его настройки.

Если Terraform просит:

Username for 'https://gitlab.example.com':

это означает, что Git не смог автоматически получить подходящие credentials.

Чаще всего проблема решается так:

  1. Создаём новый Personal Access Token.
  2. Выдаём ему только read_repository.
  3. Удаляем старый токен из credential helper.
  4. Проверяем доступ через git ls-remote.
  5. Настраиваем безопасное хранение credentials.
  6. Повторно запускаем terraform init.

Для macOS удобно использовать:

git config --global credential.helper osxkeychain

Для Windows:

git config --global credential.helper manager

Для Linux лучше использовать системное хранилище секретов или Git Credential Manager.

Вариант:

git config --global credential.helper store

работает, но хранит токен в незашифрованном виде.

Для серверов и CI/CD лучше использовать:

  • CI_JOB_TOKEN;
  • Deploy Token;
  • Project Access Token;
  • SSH Deploy Key.

Итог

Если при загрузке Terraform-модулей из приватного GitLab появился запрос логина и пароля, почти всегда проблема находится не в Terraform, а на уровне Git-аутентификации.

Возможные причины:

  • истёк старый Personal Access Token;
  • токен был отозван;
  • токен не имеет read_repository;
  • пользователь потерял доступ к проекту;
  • Git продолжает использовать старые credentials;
  • credential helper не настроен;
  • Terraform запускается в другом окружении.

Для восстановления доступа нужно:

  1. Создать новый Personal Access Token с правом read_repository.
  2. Ввести логин GitLab в поле username.
  3. Вставить PAT вместо пароля.
  4. Проверить доступ командой git ls-remote.
  5. Настроить credential helper.
  6. Повторно выполнить terraform init.

После этого Terraform сможет стабильно скачивать модули из приватного GitLab без постоянного запроса логина и пароля.

Комментарии