Skip to content
Advertisement

How can I work with micronaut 3 and google secret manager?

Currently migrating my application to Micronaut 3, I encountered one problem with micronaut-gcp. Especially with the google secret manager. I am using gradle with Kotlin DSL.

Actual configuration: (not working, using plugin io.micronaut.library version 2.0.4)

  • gradle 7.2
  • micronaut 3.0.1

Previous configuration: (working with no plugin, using micronaut-bom)

  • gradle 6.5.1
  • micronaut 2.4.0
  • micronautGcp 3.5.0

I/ The Problem

My goal is to load some secrets as key/value pairs into a property source. I followed the documentation that says to use a bootstrap.yml as follows:

micronaut:
    config-client:
        enabled: true
gcp:
    secret-manager:
      keys:
        - MY_SECRET

Then in my class I should be able to inject that secret value using the @Value annotation. Actually I am doing this in my tests. I am using the @MicronautTest annotation from jUnit5 so I have something that looks like this:

@MicronautTest
public class MyClass {
  @Value("${my.secret}")
  private String mySecret;
}

then comes the problem, when running any test, it fails in the initialization saying this:

Error instantiating bean of type  [io.micronaut.gcp.secretmanager.client.DefaultSecretManagerClient]

Message: getTransportChannel() called when needsExecutor() is true
Path Taken: new DistributedPropertySourceLocator(ConfigurationClient configurationClient,Duration readTimeout) --> new DistributedPropertySourceLocator([ConfigurationClient configurationClient],Duration readTimeout) --> new DefaultCompositeConfigurationClient([ConfigurationClient[] configurationClients]) --> new SecretManagerConfigurationClient([SecretManagerClient secretManagerClient],SecretManagerConfigurationProperties configurationProperties) --> new DefaultSecretManagerClient([SecretManagerServiceClient client],Environment environment,GoogleCloudConfiguration googleCloudConfiguration,ExecutorService executorService)
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type  [io.micronaut.gcp.secretmanager.client.DefaultSecretManagerClient]

II/ What I’ve tried ?

When I’ve seen that, I was thinking that maybe the bootstrap.yaml thing doesn’t work the I tried to use the lower lever access to secret manager using injecting SecretManagerServiceClient as follows:

@MicronautTest
public class MyClass {
  @Inject
  private SecretManagerServiceClient client;

  private void someTest() {
    String mySecret = client.getSecret("MY_SECRET");
  }
}

but got same error Message: getTransportChannel() called when needsExecutor() is true with same path taken.

I also tried to upgrade to micronaut 3.0.1 but didn’t change anything.

III/ My solution to handle this

As my problem was to retrieve a secret during the testing stage of my ci/cd process and, as I am using Google Cloud Build. I could pass the secret using the availableSecrets feature in my cloudbuild.yaml:

steps:
 ...
  - name: 'gradle'
    entrypoint: 'bash'
    args: ['./gradlew', 'test']
    secretEnv: ['MY_SECRET']
 ...

availableSecrets:
  secretManager:
  - versionName: projects/PROJECT_ID/secrets/MY_SECRET/versions/latest
    env: 'MY_SECRET'

then passing it in my application.yml:

my:
  secret: ${MY_SECRET}

and then in my code:

@MicronautTest
public class MyClass {
  @Value("${my.secret}")
  private String mySecret;
}

But I dont find this solution very satisfying as I find the bootstrap.yaml one more convenient.

If someone gets a solution for me or an idea/advice, I’ll be happy to take it.

Have a nice day !

Advertisement

Answer

I’ve been down that rabbit hole. Long story short I got past this by upgrading the google-cloud-secretmanager dependency from 1.6.4 to e.g. 2.0.2

Like so:

    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-secretmanager</artifactId>
      <version>2.0.2</version>
    </dependency>
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement