Можно ли развернуть приложение Spring Boot в App Engine и подключиться к базе данных? - PullRequest
6 голосов
/ 22 октября 2019

Я чувствую, что я хожу по кругу здесь, так что, пожалуйста, потерпите меня. Я хочу развернуть свое приложение Spring Boot на App Engine, но в отличие от простого примера , который Google предоставляет , мой требует базу данных, а это означает учетные данные. Я использую Java 11 на Standard на Google App Engine.

Мне удалось успешно подключить мое приложение, указав это в application.properties:

spring.datasource.url=jdbc:postgresql://google/recruiters_wtf?cloudSqlInstance=recruiters-wtf:europe-west2:recruiters-wtf&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=the_user&password=monkey123

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

Поскольку, очевидно, Google App Engine не может определять переменные среды любым другим способом ( в отличие от Heroku ), означает ли это, что невозможно развернуть приложение Spring Boot в App Engine и подключить его к базе данных без использованиянебезопасные / громоздкие практики? Я чувствую, что чего-то здесь не хватает.

Ответы [ 8 ]

2 голосов
/ 27 октября 2019

Предполагая, что вы можете использовать KMS или GCS для получения учетных данных, вы можете программно установить их в Spring Boot. См. Этот пост

Программная настройка источника данных в Spring Boot

2 голосов
/ 24 октября 2019

Исходя из моего понимания того, что вы описали, вы хотели бы по существу подключить загрузочное приложение Spring, работающее на Google App Engine, к базе данных, не раскрывая конфиденциальную информацию. В таком случае я смог выяснить, что Cloud KMS предлагает пользователям возможность секретного управления. В частности, приложения, которым требуются небольшие фрагменты конфиденциальных данных во время сборки или выполнения, называются секретами . Эти секреты могут быть зашифрованы и расшифрованы с помощью симметричного ключа. В вашем случае вы можете хранить учетные данные базы данных в качестве секретов. Вы можете найти более подробную информацию о процессе шифрования / дешифрования секрета здесь .

В настоящее время это три способа управления секретами :

  1. Хранение секретов в коде, зашифрованном ключом от Cloud KMS. Это решение реализует секреты на уровне приложений.
  2. Хранение секретов в хранилище в облачном хранилище, зашифрованное в покое. Вы можете использовать Cloud Storage: Bucket для хранения учетных данных вашей базы данных, а также можете назначить этому хранилищу определенную учетную запись службы. Это решение позволяет разделить системы. В случае взлома хранилища кода ваши секреты сами могут быть защищены.
  3. Использование сторонней системы управления секретами.

С точки зрения хранения секретовСами я нашел следующие шаги здесь весьма полезными для этого. Это руководство знакомит пользователей с настройкой и хранением секретов в хранилище Cloud Storage. Секрет шифруется на прикладном уровне с помощью ключа шифрования от Cloud KMS. Учитывая ваш вариант использования, это было бы отличным вариантом, поскольку ваш секрет будет храниться в корзине, а не в файле app.yaml. Кроме того, секрет, хранящийся в контейнере, даст вам возможность ограничить доступ к нему с помощью ролей учетных записей служб.

По сути, вашему приложению потребуется выполнить вызов API в Google Cloud Storage, чтобы загрузитьЗашифрованный файл KMS, содержащий секрет. Затем он будет использовать ключ, сгенерированный KMS, для расшифровки файла, чтобы иметь возможность считывать пароль и использовать его для ручного подключения к базе данных. Добавление этих дополнительных шагов приведет к реализации большего количества уровней безопасности, что и является полной идеей, отмеченной в «1029 * Примечание. Сохранение учетных данных в переменных среды удобно, но не безопасно - рассмотрите более безопасное решение, такое как Cloud KMS, для сохранения секретов. safe. '”в репозитории Google для Cloud SQL.

Надеюсь, это поможет!

1 голос
/ 02 ноября 2019

Как вы указали, в App Engine нет встроенного способа задания переменных среды, кроме файла app.yaml. Я не эксперт в Spring Boot, но если вы не можете установить / переопределить некоторые хуки для инициализации env var из Java-кода до application.properties оценки, вам нужно будет установить их во время сборки.

Вариант 1. Использование Cloud Build

Я знаю, что вы на самом деле не хотите использовать Cloud Build, но это будет что-то вроде этого.

Во-первых, следуя инструкциям здесь (после создания KeyRing и CryptoKey в KMS и предоставления доступа к учетной записи службы Cloud Build) с вашего терминала зашифруйте переменную среды, используя KMS, и верните ее представление base64:

echo -n $DB_PASSWORD | gcloud kms encrypt \
  --plaintext-file=- \  # - reads from stdin
  --ciphertext-file=- \  # - writes to stdout
  --location=global \
  --keyring=[KEYRING-NAME] \
  --key=[KEY-NAME] | base64

Далее, скажем, у вас есть файл app.yaml, подобный этому:

runtime: java11
instance_class: F1

env_variables:
  USER:  db_user
  PASSWORD: db_passwd

создайте файл cloudbuild.yaml, чтобы определить шаги сборки :

steps:
# replace env vars in app.yaml by their values from KMS
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args: ['-c', 'sed -i "s/TEST/$$PASSWORD/g" src/main/appengine/app.yaml']
  secretEnv: ['PASSWORD']
- name: 'gcr.io/cloud-builders/mvn'
  args: ['clean']
- name: 'gcr.io/cloud-builders/mvn'
  args: ['package']
- name: 'gcr.io/cloud-builders/mvn'
  args: ['appengine:deploy']
  timeout: '1600s'
secrets:
- kmsKeyName: projects/<PROJECT-ID>/locations/global/keyRings/<KEYRING_NAME>/cryptoKeys/<KEY_NAME>
  secretEnv:
    PASSWORD: <base64-encoded encrypted password>
timeout: '1600s'

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

gcloud builds submit .

Преимущество этого метода заключается в том, что ваш локальный файл app.yaml содержит только значения заполнителей и может быть безопасно зафиксирован. Или вы можете даже настроить эту сборку так, чтобы она автоматически запускалась при каждой фиксации в удаленном репозитории.

Опция 2: локально с помощью сценария bash

Вместо запуска mvn appengine:deploy чтобы развернуть ваше приложение, вы можете создать скрипт bash, который заменит значения в app.yaml, развернуть приложение и сразу удалить значения .. Что-то вроде:

#!/bin/bash
sed -i "s/db_passwd/$PASSWORD/g" src/main/appengine/app.yaml'
mvn appengine:deploy
sed -i "s/$PASSWORD/db_passwd/g" src/main/appengine/app.yaml'

и выполнить этот bashсценарий вместо запуска команды maven.

0 голосов
/ 02 ноября 2019

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

1 - без Docker

Можете ли вы использовать этот подход через env или консоль?

Мы используем (определяемые Spring Boot) переменные окружения. Это стандартный способ сделать это:

SPRING_DATASOURCE_USERNAME=myusername
SPRING_DATASOURCE_PASSWORD=mypassword

В соответствии со спецификацией Spring Boot это отменяет любое значение переменных application.properties. Таким образом, вы можете указать имя пользователя и пароли по умолчанию для разработки и отменить это во время (тестового или) рабочего развертывания.

Другой способ описан в этом посте :

spring.datasource.url = ${OPENSHIFT_MYSQL_DB_HOST}:${OPENSHIFT_MYSQL_DB_PORT}/"nameofDB"
spring.datasource.username = ${OPENSHIFT_MYSQL_DB_USERNAME}
spring.datasource.password = ${OPENSHIFT_MYSQL_DB_PASSWORD}

2 - Подход, подобный Docker через консоль

Ваш вопрос описан в этом посте . Решение по умолчанию работает с «секретами». Они специально созданы для этого. Вы можете преобразовать любой секрет (в виде файла) в переменную окружения в процессе создания и развертывания приложения. Это простое действие, которое описано во многих постах. Ищите новые подходы.

0 голосов
/ 01 ноября 2019

Вам следует воспользоваться службой управления ключами GCP: https://cloud.google.com/kms/

0 голосов
/ 01 ноября 2019

Вы можете попробовать зашифровать пароль в свойствах приложения. Взгляните на http://mbcoder.com/spring-boot-how-to-encrypt-properties-in-application-properties/

0 голосов
/ 30 октября 2019

Я чувствую, что это легко сделать. Я использовал следующие свойства в своем весеннем загрузочном приложении, которое подключается к общедоступному экземпляру Google MySQL.

spring.datasource.url=jdbc:postgresql://IP:5432/yourdatabasename
spring.datasource.platform = postgres
spring.datasource.username = youruser
spring.datasource.password = yourpass

Остальное позаботится JpaRepository. Я надеюсь, что это поможет вам.

Дайте мне знать, нужна ли какая-либо помощь.

0 голосов
/ 27 октября 2019

Я бы, вероятно, предложил бы комбинацию Spring Cloud Config & Google Runtime Configuration API с вашим Spring Boot приложением.

Spring Cloud Config - это компонент, который отвечает за извлечение конфигурации из удаленных мест и ее обслуживание дляваш Spring Boot во время инициализации / загрузки. Удаленные места могут быть чем угодно. например, репозиторий GIT широко используется, но для вашего случая вы можете сохранить конфигурацию в Google Runtime Configuration API.

Таким образом, поток выборки будет выглядеть следующим образом.

Your Spring Boot App(with Config Client) --> Spring Cloud Config Server --> Google Runtime Configuration API

Это требует, чтобы вы запустили Spring Cloud Config Server в качестве другого приложения в GCP и включили связь между многими из ваших приложений Spring Boot и централизованным Config Server, который взаимодействует с Google Runtime API.

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

https://cloud.spring.io/spring-cloud-config/reference/html/

https://docs.spring.io/spring-cloud-gcp/docs/1.1.0.M1/reference/html/_spring_cloud_config.html

https://cloud.google.com/deployment-manager/runtime-configurator/reference/rest/

Пример примера конфигурации GCP Spring Cloud.

https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-config-sample

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...