Installing Jenkins using terraform in Kubernetes in Yandex Cloud with letsencypt

https://habr.com/ru/articles/683844/

В этой статье будет следующее:

  • Заведение DNS домена на reg.ru.

  • Управление DNS зоной в Yandex DNS c помощью terraform.

  • Создание Kubernetes в Yandex Cloud.

  • Резервируем внешний статический IP адрес.

  • Установка Jenkins c помощью terraform модуля helm_release.

  • Создание ClusterIssue(Issue) для создания letsencypt сертификата.

Быстрая установка Jenkins с помощью terraform в Kubernetes в Yandex Cloud с letsencypt.

Скачать репозиторий:

git clone https://github.com/patsevanton/infrastructure-as-a-code-example.git

Перейти в каталог terraform-helm-release-jenkins:

cd terraform-helm-release-jenkins

Заполнить private.auto.tfvars на базе шаблона private.auto.tfvars.example.

Запустить установку:

k8s_install.sh

Разберем подробнее.

Заводим DNS домен на reg.ru — mycompany.ru или mycompany.org.ru. В настройках домена на вкладке "DNS-серверы и управление зоной" указываем DNS Yandex Cloud:

  • ns1.yandexcloud.net

  • ns2.yandexcloud.net

DNS зона управляется с помощью terraform кода. Документация — https://cloud.yandex.ru/docs/dns/.

Так как у zone на конце должна быть точка, то используем метод join для соединения нашего домена и точки.

Создание DNS записи.

В имени DNS записи на конце необходима точка, поэтому используем метод join для соединения DNS записи и точки. Код:

Поле data — список IP адресов, на которые должны резолвиться эта DNS запись.

  • Создание сервисного аккаунта.

Перед созданием Kubernetes кластера необходимо рассказать о создание сервисного аккаунта. Название сервисного аккаунта — sa-k8s-admin.

Лучше использовать yandex_resourcemanager_folder_iam_member вместо yandex_resourcemanager_folder_iam_binding, так как не всегда работает корректно. У меня на другом коде вызывает ошибку. Issue — https://github.com/yandex-cloud/terraform-provider-yandex/issues/267 и https://github.com/yandex-cloud/terraform-provider-yandex/issues/283.

В role указываем какие права имеет сервисный аккаунт. Более подробно в документации https://cloud.yandex.ru/docs/iam/concepts/access-control/roles.

Создание kubernetes кластера в Yandex Cloud.

Для создание kubernetes кластера в Yandex Cloud используется уже обычный terraform код:

Если кластер тестовый, то можно снизить стоимость используя 50% ядра и использовать прерываемые виртуальные машины.

Сеть и внешний статический IP адрес.

Указываем сеть:

Указываем подсеть:

Указываем внешний статический IP адрес:

Неважно какой будет IP. В DNS запись будет добавлен этот IP.

Jenkins установливаем c помощью terraform модуля helm_release.

Рассмотрим helm_release.tf:

provider "helm" описывает настройки подключения к kubernetes для helm.

Создаем ingress-nginx.

В terraform опции --set key=value передаются так:

В данном случае для controller.service.loadBalancerIP указываем внешний статический IP адрес.

Устанавливаем cert-manager по аналогии с ingress-nginx.

Устанавливаем jenkins.

Jenkins helm чарту на вход необходимо указать value.yaml с нашими настройками.

Есть 2 способа указать value.yaml.

Первый способ использовать готовый и настроеный value.yaml в текущей директории:

Второй способ использовать yamlencode для перевода terraform кода в yaml код.

Как получить terraform код из yaml кода?

Подготавливаете и настраиваете value.yaml, а затем используя вот такую команду переводите в terraform код:

В моем случае value.yaml имеет другое название:

Я использую yamlencode, потому что внутри yamlencode кода ссылаюсь на terraform переменные, а так же потому что job лежат отдельно.

Полученный код вставляете в local.jenkins_values_google_login

Затем вместо ваших данных:

используйте terraform переменные

Рассмотрим local.jenkins_values_google_login.

В корне стоит controller от которого идут все настройки.

Для настройка jenkins из кода используются jcasc, job-dsl. Примеры jcasc https://github.com/jenkinsci/configuration-as-code-plugin

Более подробно — https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/demos/global-matrix-auth/README.md

В configScripts каждый блок EOT это отдельный файл в контейнере jenkins. systemMessage системное сообщение.

Указываем файл job:

Указываем список view:

Указываем как мы будет входить в jenkins:

Я использую googleOAuth2. Можно еще использовать local, ldap и другие.

Дополнительные плагины jenkins:

Настройка Ingress:

Если у вас нет letsencrypt, то вы удаляете cert-manager.io/cluster-issuer.

Указываем javaOpts чтобы запускать Job-DSL скрипты:

Сравнение настроенный yaml и yamlencode из terraform кода.

Чем плох настроенный yaml в качестве value.yaml для helm чарта относительно yamlencode ?

  • Он длинный.

  • В yaml коде нельзя вынести кусок кода (например job) в отдельный файл.

  • Для формирования заполненого настроенного value.yaml необходимо использовать templatefile. Мне кажется это лишнее.

В JCasC.configScripts каждый блок до вертикальной черты (|) будет сохранен как отдельный файл в контейнере Jenkins.

В Yaml формате все job нужно расписывать. Если сравнить:

и чтение файла job, то вынос файла лучшее красивее и читабельнее:

Добавление kind: ClusterIssuer в Kubernetes.

Если мы будем добавлять kind: ClusterIssuer как resource "kubernetes_manifest" и добавим как подключатся к Kubernetes используя provider "kubernetes", то получим ошибку:

Мы не можем развернуть resource "kubernetes_manifest" в котором ссылаемся на другой ресрус — https://github.com/hashicorp/terraform-provider-kubernetes/issues/1380

Поэтому создадим файл ClusterIssuer.yaml.tpl и будем формировать его через templatefile передав всего 1 переменную email_letsencrypt.

Вот мы с вами и прошли то, что напланировали в самом начале.

Last updated

Was this helpful?