Автоматизация с террафом (3 частью серии)
Этот пост смотрит на развертывание одного экземпляра хранилища в облаке Google с использованием террафора; И предназначен для тех, кто уже использует террафору и облако Google, и смотрит в использование хранилища.
Хранилище Служба управления секретами, существует много способов и преимуществ для его использования, но по сути вам больше не приходится к жестким кодам, таких как пароли базы данных в ваш код; И вы можете получить ваши приложения запросить секреты во время выполнения, когда они нуждаются в них. Подумайте об этом, как менеджер паролей, которые могут использовать ваши приложения/микросервисы.
Три последствия этого есть:
- Безопасность, вы не оставляете свои учетные данные базы данных, лежащие в вашем коде или окружении.
- Вы можете автоматически генерировать и управлять паролями, а не на необходимость копирования/вставки нового пароля вручную на многих местах, которые они могут быть использованы.
- Вы можете добавить правила доступа к паролям, основанным на том, кто их запрашивает. Производственные приложения могут получить доступ к производственным паролям, приложения для разработки не могут.
Примером настройки пароля автоматически вращается вверх по экземпляру RDB в облаке Google в Terraform
resource "google_sql_database_instance" "prod" { ... } resource "random_password" "prod" { length = 16 } resource "google_sql_database" "prod" { name = "prod_db" instance = google_sql_database_instance.prod.name } resource "google_sql_user" "prod" { name = "prod_user" instance = google_sql_database_instance.prod.name password = random_password.prod.result }
Вышеуказанный террафом Code создает новый RDB в Google Cloud, и создает базу данных под названием prod_db
, пользователь под названием prod_user
и назначает его случайным в 16-символьном пароле.
На данный момент, если вы не используете хранилище, вам придется заглянуть на то, что был этот случайной 16-символьный пароль, а затем перейти настроить кучу приложений или среды для его использования. Однако с хранилищем, вы можете вместо этого есть эти строки в вашем террафоре:
resource "vault_generic_secret" "prod_db" { path = "secret/production/db" data_json = jsonencode({ username = google_sql_user.prod.name password = google_sql_user.prod.password db = google_sql_database.prod.name host = google_sql_database.prod.ip_address.0.ip_address }) }
Теперь любое приложение, которое авторизовано для доступа к Секрет/Производство/БД
Может не только сделать не только случайный пароль, с которым вы никогда не видели или не должны иметь дело, но и имя пользователя, базу данных и даже хост IP базы данных, все значения, которые могут время от времени изменять по соображениям безопасности или передислокации. Вы можете повторить процесс для настройки DB разработки и установить путь секрета в Секрет/Development/DB
Отказ Теперь приложения могут переключаться между двумя базами данных, просто изменив, какие секретные его выводятся.
Пример клиентского кода Python для этого (и это очень упрощено)
import requests role = "production" vault_addr = "https://vault.example.com:8200" secret_path = "production/db" # fetch JWT from metadata server req_jwt = requests.get( "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity", headers={"Metadata-Flavor": "Google"}, params={"audience": f"http://vault/{role}", "format": "full"}, ) jwt = req_jwt.text # authenticate with Vault req_token = requests.post( f"{vault_addr}/v1/auth/gcp/login", json={"role": role, "jwt": jwt}), ) token = req_token.json()["auth"]["client_token"] # request hte secret req_secret = requests.get( f"{vault_addr}/v1/secret/data/{secret_path}", headers={"x-vault-token": token}, ) secret = req_secret.json()["data"]["data"]
Первый запрос выбирает JWT с сервера Metadata VM, этот JWT является доказательством этого приложения, которое он работает внутри авторизованного сервера. Этот JWT — это то, как вы избегаете необходимости с помощью жестких паролей, поскольку только приложения, работающие внутри VM, могут получить JWT.
Второй запрос аутентифицируется против хранилища, используя JWT (и Vault, должно быть заранее установлено, чтобы позволить этому методу аутентификации) и получает краткосрочный токен доступа.
Третий и окончательный запрос используют этот токен доступа, чтобы получить секрет, который ему нужно. Приложение может кэшировать токен или JWT для повторного использования позже.
Приведенный выше код упрощен и не включает в себя какую-либо проверку ошибок. У меня есть Vault.py
Сценарий, содержащий лучший завернутый код, который я могу включить во все услуги в качестве библиотеки, чтобы дать им доступ к хранилищу.
У Vault также есть CLI и UI, чтобы помочь вам работать с ним вручную.
Есть много способов развертывания хранилища, а хранилище может работать как кластер и стать очень доступным. Однако самый простой (и, возможно, самый дешевый) способ сделать это — это запустить его как программу в одном виртуальной машине. Это достаточно хорошо для использования и тестирования света, вы всегда можете расширить его позже.
Я просто собираюсь идти вперед и сбросить код моего террафора для этого:
resource "google_compute_instance" "vault" { name = "vault" machine_type = "e2-small" zone = "us-central1-a" tags = [google_compute_firewall.vault.name] metadata = { ssh-keys = "terraform:${tls_private_key.vault.public_key_openssh}" } boot_disk { initialize_params { image = "ubuntu-minimal-2004-lts" } } network_interface { network = google_compute_network.default.name access_config { nat_ip = google_compute_address.vault.address } } service_account { email = google_service_account.vault.email scopes = [ "cloud-platform" ] } provisioner "file" { content = <
Это немного глоток, и может быть упрощенным и модульным. Два файловых давателя должны загружаться в шаблоны из файла, а не определены встроенную строку, чтобы сохранить код более короткими, но я консировал его, чтобы пост легче следовать.
Я постараюсь объяснить, что здесь происходит. Большая часть верхней половины — это стандартные вещи для развертывания VMS Google с террафом, это создает E2-маленький
Экземпляр в US-Central1-A
Использование изображения Ubuntu 20.04. Мы генерируем временный ключ SSH, чтобы Террафом мог войти и выполнять работу в развертывании света (фактические линии для этого ниже).
Первый Provisioner "Файл"
Блок развертывает файл конфигурации для террафора. Этот файл конфигурации содержит ведро хранения, которое ему необходимо получить доступ, а TLS/SSL и другой конфиг.
Второй Provisioner "Файл"
Определение системы Systemd Service для Terraform, в основном в основном ботистота.
Третий и четвертый даватели предназначены для копирования в SSL Certs для HTTPS. То, как у меня есть эти настройки похожи на мой предыдущий пост:
Автоматизация получения подстановочного знака Сертификаты HTTPS HTTPS для вашего домена с террафом
Юань Гао · 13 сен. 13 ’20 · 6 мин читать
Далее Provisioner "Remote_exec"
завершает настройку — он работает APT обновление и устанавливает unzip
; загружает хранилище с серверов Hashicorp и устанавливает его; затем перемещает все остальные файлы из папки/TMP, где они были сброшены (в основном из-за проблем с разрешениями файла); а затем включает и запускает сервис.
Вышеуказанный скрипт зависит от нескольких других линий, которые я отделил, чтобы держать вещи, которые можно читать:
locals { vault_version = "1.5.3" vault_domain = "vault.example.com" }
Это некоторые локальные переменные, они облегчают выбрать версию Vault, вы хотите установить. И где хранилище будет, когда он полностью развернут.
resource "tls_private_key" "vault" { algorithm = "RSA" }
Это генерирует ключ SSH для доступа к хранилищу, она довольно ботинка для развертывания VM Terraform VM
resource "google_compute_address" "vault" { name = "vault" }
Это резервирует IP-адрес для экземпляра Vault VM. Это не требуется строго, VM без оговорок IP-адреса по умолчанию приобретает эфемерную. Однако одна практичность заключается в том, что если вы должны порезовать Vault Vum по любой причине и создать новый, он получит новый IP-адрес, который приведет к обновлению DNS, который займет несколько минут, оставляя вас с некоторыми простоя. Немного лучше зарезервировать IP.
resource "google_compute_firewall" "vault" { name = "vault" network = google_compute_network.default.name allow { protocol = "tcp" ports = ["9800"] } source_ranges = ["0.0.0.0/0"] target_tags = ["vault"] }
Это настройка брандмауэра для разрешения доступа к хранилищу
resource "google_service_account" "vault" { account_id = "vault" display_name = "Vault Service Account" description = "For vault state storage backend" } resource "google_service_account_key" "vault" { service_account_id = google_service_account.vault.name } resource "google_project_iam_member" "vault-iam" { project = data.google_project.project.project_id role = "roles/iam.serviceAccountUser" member = "serviceAccount:${google_service_account.vault.email}" }
Это учетная запись услуг Vault. Хранилище необходимо использовать эту учетную запись услуг по двум причинам: доступа к его ведрам хранения и аутентификации генерируемых GCP JWTS. Ключ сервиса необходим позже.
resource "google_storage_bucket" "vault" { project = google_project.project.project_id name = "" location = "us-central1" uniform_bucket_level_access = true } resource "google_storage_bucket_iam_member" "vault" { bucket = google_storage_bucket.vault.name role = "roles/storage.admin" member = "serviceAccount:${google_service_account.vault.email}" }
Это создает ведро хранения секретов хранилища. Для получения дополнительной информации о том, как Sault шифрует секреты, см. их документация
Если вы были запущены вышеупомянутым, и предполагая, что у вас есть все остальные ресурсы, установленные, это будет вращаться и установить экземпляр хранилища, готов к работе. Пожалуйста, внимательно пройдите HCl, вы найдете ссылки на данные, о которых я не говорил в этом посте, включая такие вещи, как сетевые конфиги, SSL-сертификаты и т. Д.
После развертывания хранилище находится в пустом шифере, в том числе не сгенерированных ключей. На этом этапе вы, вероятно, хотите сначала добраться до экземпляра и генерировать корневые клавиши, прежде чем кто-то другой. Вы можете сделать это через CLI, либо через веб-интерфейс, фактический акт настройки и операционного хранения находится за пределами объема этого поста, который охватывает только примеры развертывания одного экземпляра в облаке Google с террафом. Для деталей использования я предлагаю проверить много учебных пособий на их сайте
Как только вы генерируете ключи, вам нужно «отменить» хранилище, прежде чем настроить.
Настройка хранилища можно сделать вручную, используя CLI или UI, но гораздо легче сделать это через террафору. Незначительная сложность настройки хранилища, которые были развернуты в VM с использованием Terraform, заключаются в том, что есть ручной шаг, в котором вам нужно пойти настроить Vault вручную после того, как VM идет в прямом эфире, и до того, как остальная часть, связанная с хранилищем Terraform Code. Это может привести к тому, что некоторые запутанные тупики в коде террафора есть несколько способов, используя ручное ожидание, а также Defends_on
Но я еще не нашел хорошего способа, я обычно разлучал конфигурацию в отдельном рабочем пространстве террафора или просто утверждаю с ошибками, пока я иду вручную отменить.
Как именно вы хотите настроить Vault, будет соответствовать вашим требованиям, но вот несколько примеров того, что я использую:
provider "vault" { address = "https://${var.vault_domain}:8200" }
Сначала вам нужен провайдер. Посмотреть Документация Для получения более подробной информации, как вам сначала понадобится ваш токен, предоставляемый либо здесь, либо как часть вашей среды.
resource "vault_policy" "prod_read" { name = "prod_read" policy = <
Вот политика для ролей, которые могут читать производственные секреты
resource "vault_gcp_auth_backend" "vault_gcp" { credentials = base64decode(google_service_account_key.vault.private_key) } resource "vault_gcp_auth_backend_role" "production" { role = "production" type = "iam" bound_projects = [ data.google_project.project.project_id ] bound_service_accounts = [ google_service_account.production.email ] token_policies = [ "secrets_reader" ] max_jwt_exp = 3600 }
Это позволяет проводить аутентификацию GCP JWT ранее. Private_key — это то, что сгенерировано выше. Обратите внимание на bound_projects.
и bound_service_accounts.
Вы захотите добавить учетные записи службы, с которых принимаются JWTS.
Есть много дополнительной конфигурации, которая выходит за пределы объема этого поста в блоге, но, надеюсь, этот блог дает некоторое руководство о том, как настроить и управлять единым экземпляром Vault для тестирования и оценки или небольшого развертывания.
Обложка Фото Джейсон Дент на Бессмысленно
Автоматизация с террафом (3 частью серии)
Оригинал: «https://dev.to/meseta/automating-deploying-vault-a-password-manager-for-your-code-with-terraform-3djn»