使用github操作将开源Spring Boot应用程序部署到Google Cloud

时间:2020-01-28 15:37:19

标签: spring-boot google-app-engine github-actions

我有开源的spring boot应用程序,我想使用github action CI将其部署到Google Cloud App Engine。

我的问题是,如何在不对生产环境进行硬编码/公开属性(例如:

)的情况下完成所有操作?
spring.cloud.gcp.sql.database-name
spring.cloud.gcp.sql.instance-connection-name
spring.datasource.password
spring.datasource.username
google-project-id
google cloud project service account key

我的想法是将所有这些值放入github机密,在CI中检索它们,使CI打包具有给定属性的应用程序并部署它。

我的问题是,我可以打包应用程序以替换application-prod.properties中的给定属性吗?

我的另一个想法只是为给定属性定义环境变量,并让应用程序在运行时检索它们,但是我不确定应用引擎是否支持设置环境变量。

2 个答案:

答案 0 :(得分:1)

我建议使用Secret Manager documentation将环境变量安全地存储在GAE中:

秘密是一个项目全局对象,其中包含 元数据和秘密版本。元数据可以包括复制 位置,标签和权限。秘密版本存储 实际的机密数据,例如API密钥或凭据。

Secret Manager conceptual overview

在这里您可以找到Java实现:


import com.google.cloud.secretmanager.v1beta1.AccessSecretVersionRequest;
import com.google.cloud.secretmanager.v1beta1.AccessSecretVersionResponse;
import com.google.cloud.secretmanager.v1beta1.AddSecretVersionRequest;
import com.google.cloud.secretmanager.v1beta1.CreateSecretRequest;
import com.google.cloud.secretmanager.v1beta1.ProjectName;
import com.google.cloud.secretmanager.v1beta1.Replication;
import com.google.cloud.secretmanager.v1beta1.Secret;
import com.google.cloud.secretmanager.v1beta1.SecretManagerServiceClient;
import com.google.cloud.secretmanager.v1beta1.SecretPayload;
import com.google.cloud.secretmanager.v1beta1.SecretVersion;
import com.google.protobuf.ByteString;

public class Quickstart {

  public void quickstart() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String secretId = "your-secret-id";
    quickstart(projectId, secretId);
  }

  public void quickstart(String projectId, String secretId) throws Exception {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {

      // Build the parent name from the project.
      ProjectName parent = ProjectName.of(projectId);

      // Create the parent secret.
      CreateSecretRequest createRequest =
          CreateSecretRequest.newBuilder()
              .setParent(parent.toString())
              .setSecretId(secretId)
              .setSecret(
                  Secret.newBuilder()
                      .setReplication(
                          Replication.newBuilder()
                              .setAutomatic(Replication.Automatic.newBuilder().build())
                              .build())
                      .build())
              .build();

      Secret secret = client.createSecret(createRequest);

      // Add a secret version.
      AddSecretVersionRequest addRequest =
          AddSecretVersionRequest.newBuilder()
              .setParent(secret.getName())
              .setPayload(
                  SecretPayload.newBuilder()
                      .setData(ByteString.copyFromUtf8("hello world!"))
                      .build())
              .build();
      SecretVersion version = client.addSecretVersion(addRequest);

      // Access the secret version.
      AccessSecretVersionRequest accessRequest =
          AccessSecretVersionRequest.newBuilder().setName(version.getName()).build();
      AccessSecretVersionResponse response = client.accessSecretVersion(accessRequest);

      // Print the secret payload.
      //
      // WARNING: Do not print the secret in a production environment - this
      // snippet is showing how to access the secret material.
      String payload = response.getPayload().getData().toStringUtf8();
      System.out.printf("Plaintext: %s\n", payload);
    }
  }
}

答案 1 :(得分:0)

我最终得到了这个解决方案:

我不会将任何敏感属性提交给git。在CI中,在部署和打包应用程序之前,我用此动作https://github.com/christian-draeger/write-properties编写了这些敏感属性,并从GithubSecrets获取了给定的值。

ie:编写数据库密码属性的步骤:

  - name: set database password
    uses: christian-draeger/write-properties@1.0.0
    with:
      path: './src/main/resources/application-prod.properties'
      property: 'spring.datasource.password'
      value: ${{secrets.database_password}}

我喜欢这种设置,因为我要在打包之前设置这些属性-在目标环境中不会对其进行硬编码。

尽管有一个不便,但此操作似乎一次只能写入一个属性,因此必须为每个属性多次取消给定的步骤。