Как создавать образы докеров с предустановленными провайдерами terraform

Я пытаюсь создать образ докера, который содержит все необходимые плагины/поставщики, необходимые для нескольких исходных репозиториев, чтобы при запуске автоматизированного terraform validate ему не приходилось загружать гигабайты избыточных данных.

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

Вопрос

  1. Как я могу предварительно скачать всех провайдеров и плагины
  2. Скажите CLI использовать эти предварительно загруженные плагины И
  3. также скажите ему, что если он не найдет то, что ему нужно локально, то он может пойти в сеть

Ниже приведены соответствующие файлы: .terraformrc

plugin_cache_dir   = "$HOME/.terraform.d/plugin-cache"
disable_checkpoint = true
provider_installation {
  filesystem_mirror {
    path    = "$HOME/.terraform/providers"
  }
  direct {
  }
}

tflint (не относится к этому вопросу, но отображается в Dockerfile ниже)

plugin "aws" {
  enabled = true
  version = "0.21.1"
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}
plugin "azurerm" {
  enabled = true
  version = "0.20.0"
  source  = "github.com/terraform-linters/tflint-ruleset-azurerm"
}

Dockerfile

FROM ghcr.io/terraform-linters/tflint-bundle AS  base
LABEL name=tflint
RUN adduser -h /home/jenkins -s /bin/sh -u 1000 -D jenkins

RUN apk fix && apk --no-cache --update add git terraform openssh
ADD .terraformrc /home/jenkins/.terraformrc
RUN mkdir -p  /home/jenkins/.terraform.d/plugin-cache/registry.terraform.io

ADD .tflint.hcl /home/jenkins/.tflint.hcl
WORKDIR /home/jenkins
RUN tflint --init

FROM base AS build

ARG SSH_PRIVATE_KEY

RUN mkdir /root/.ssh && \
    echo "${SSH_PRIVATE_KEY}" > /root/.ssh/id_ed25519 &&  \
    chmod 400 /root/.ssh/id_ed25519 &&  \
    touch /root/.ssh/known_hosts &&  \
    ssh-keyscan mygitrepo >> /root/.ssh/known_hosts


RUN git clone git@mygitrepo:wrai/tools/g.git

RUN git clone git@mygitrepo:myproject/a.git && \
    git clone git@mygitrepo:myproject/b.git && \
    git clone git@mygitrepo:myproject/c.git && \
    git clone git@mygitrepo:myproject/d.git && \
    git clone git@mygitrepo:myproject/e.git && \
    git clone git@mygitrepo:myproject/f.git

RUN ls -1d */ | xargs -I {} find {} -name '*.tf' | xargs -n 1 dirname | sort -u |  \
    xargs -I {} -n 1 -P 20 terraform -chdir = {} providers mirror /home/jenkins/.terraform.d

RUN chown -R jenkins:jenkins /home/jenkins
USER jenkins

FROM base AS a
COPY --from=build /home/jenkins/a/ /home/jenkins/a
RUN cd /home/jenkins/a && terraform init

FROM base AS b
COPY --from=build /home/jenkins/b/ /home/jenkins/b
RUN cd /home/jenkins/b && terraform init

FROM base AS c
COPY --from=build /home/jenkins/c/ /home/jenkins/c
RUN cd /home/jenkins/c && terraform init

FROM base AS azure_infrastructure
COPY --from=build /home/jenkins/d/ /home/jenkins/d
RUN cd /home/jenkins/d && terraform init

FROM base AS aws_infrastructure
COPY --from=build /home/jenkins/e/ /home/jenkins/e
RUN cd /home/jenkins/e && terraform init
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
0
0
75
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
  1. Постановочные плагины:

Это проще всего сделать с помощью настройки каталога кеша плагинов в CLI. Это заменяет старое использование аргумента -plugin-dir=PATH для команды init. Вы также можете установить зеркало файловой системы в каждом terraform блоке в конфигурации корневого модуля, но это будет обременительно для вашего варианта использования. В вашей ситуации вы уже настраиваете это в своем .terraformrc, но filesystem_mirrorpath конфликтует с plugin_cache_dir. Вы хотели бы разрешить этот конфликт или, возможно, полностью удалить зеркальный блок.

  1. Используйте поэтапные плагины:

Поскольку этот параметр фиксируется в файле конфигурации CLI в Dockerfile, он будет автоматически использоваться в будущих командах.

  1. При необходимости загрузите дополнительные плагины:

Это поведение команды init по умолчанию, поэтому с вашей стороны не требуется никаких дополнительных действий.

Примечание:

Пользователь jenkins обычно является /sbin/nologin для оболочки и /var/lib/jenkins для домашнего каталога. Если целью этого образа Docker является агент сборки Jenkins, возможно, вы захотите, чтобы пользовательская конфигурация jenkins была больше согласована со стандартом.

Спасибо за детали Дженкинса - у вас есть ссылка, которую я могу проверить, чтобы понять стандарт? Потому что, да, это для агента. Кэш плагинов — это правильный баланс между сложностью проектирования и уменьшенной избыточностью. Спасибо

Christian Bongiorno 09.02.2023 19:00

TL;DR:

  1. Настройте каталог кэша плагинов terraform
  2. Создайте каталог с одним файлом TF, содержащим блок required_providers
  3. Беги terraform init оттуда

...

Я наткнулся на этот вопрос, когда пытался понять то же самое.

Сначала я попытался использовать подразумеваемое зеркало файловой системы, запустив terraform providers mirror /usr/local/share/terraform/plugins в каталоге, содержащем только один файл terraform, содержащий блок required_providers. Это работает нормально, пока вы используете только те версии провайдеров, которые вы зеркалировали.
Однако невозможно использовать версию провайдера, отличную от той, которую вы отразили, потому что:

Terraform просканирует все зеркальные каталоги файловой системы, чтобы увидеть, какие провайдеры там размещены, и автоматически исключит всех этих провайдеров из подразумеваемой прямой блокировки.

Я обнаружил, что лучше использовать каталог кеша плагинов. EDIT: вы можете предварительно загрузить плагины, установив TF_PLUGIN_CACHE_DIR в какой-либо каталог, а затем запустив terraform init в каталоге, который только объявляет required_providers.

Ранее переработанный материал ниже:
Оставалось только одно препятствие: terraform providers mirror загружает провайдеров в упакованном макете:

Упакованный макет: HOSTNAME/NAMESPACE/TYPE/terraform-provider-TYPE_VERSION_TARGET.zip — это zip-файл дистрибутива, полученный из исходного реестра провайдера.

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

Распакованный макет: HOSTNAME/NAMESPACE/TYPE/VERSION/TARGET — это каталог, содержащий результат распаковки zip-файла дистрибутива провайдера.

Итак, я преобразовал упакованный макет в распакованный с помощью find и parallel:

find path/to/plugin-dir -name index.json -exec rm {} +`  

find path/to/plugin-dir -name '*.json' | parallel --will-cite 'mkdir -p {//}/{/.}/linux_amd64; unzip {//}/*.zip -d {//}/{/.}/linux_amd64; rm {}; rm {//}/*.zip'

Мне нравится ваш сверхинженерный подход :) Я действительно кое-чему научился

Christian Bongiorno 09.02.2023 18:59

Другие вопросы по теме