spring-cloud / spring-cloud-config

External configuration (server and client) for Spring Cloud
Apache License 2.0
1.96k stars 1.29k forks source link

Found what looks like an issue with spring.cloud.config.awsS3 with multiple profiles #2018

Open AnthonyCavanagh opened 2 years ago

AnthonyCavanagh commented 2 years ago

I have a application.yml and 4 more files application-local.ym, application-dev.yml, application-qa.yml, application-prod.yml. The way it works is that spring: profiles: active: @activatedProperties@

Will depending on what @activatedProperties@ is, will pull the correct application so if @activatedProperties@ is local, it will pull application-local.ym.

The problem is that to run

cloud: config: server: awss3: bucket: hp-fetcher-config region: us-west-2 order: 1

I need to replace

spring: profiles: active: @activatedProperties@

with spring: profiles: active: awss3

I cant find any docs or examples that show how to run awss3 in multiple profiles

ryanjbaxter commented 2 years ago

You have not stated what the actual problem is.

Please learn how to format code on GitHub.

AnthonyCavanagh commented 2 years ago

I need to be able to run awss3: with multiple profiles. I have the following application.yml that calls a eureka service discovery , the eureka service discovery is calls relied on what @activatedProperties@ resolves to.

server.port: 8080
spring:
  profiles:
    active: @activatedProperties@
  application:
    name: @artifactId@
  # do not serialize nulls
  jackson:
    default-property-inclusion: NON_NULL
    mapper:
      accept-case-insensitive-enums: true

# service discovery
eureka:
  client:
    validateCertificates: false
    registerWithEureka: true
    fetchRegistry: true
    healthcheck:
      enabled: true
    serviceUrl:
      defaultZone: "http://${eureka.server.host}:8761/eureka/"
  instance:
    statusPageUrl: "http://${eureka.hostname}/actuator"
    healthCheckUrl: "http://${eureka.hostname}/actuator/health"
    homePageUrl: "http://${eureka.hostname}/"
    nonSecurePortEnabled: true
    preferIpAddress: false

if @activatedProperties@ resolves to local, then it calls another yml file application-local.yml

server.port: 8082
eureka:
  client:
    serviceUrl:
      defaultZone: "http://localhost:8761/eureka/"

This works, the problem arises when make this a config service using awss3. Because to use awss3 you have to make it the active profile spring:profiles:active:awss3. Which means I can no longer pass in @activatedProperties@ to set the correct discovery service address.

spring:
  profiles:
    active: 
      awss3
  application: 
    name: HP-FETCHER-CONFIG-SERVICE

  cloud:
    config:
      server:
        awss3:
          bucket: hp-fetcher-config
          region: us-west-2
          order: 1

# service discovery
eureka:
  client:
    validateCertificates: false
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: "http://${eureka.server.host}:8761/eureka/"
  instance:
    statusPageUrl: "http://${eureka.hostname}/actuator"
    healthCheckUrl: "http://${eureka.hostname}/actuator/health"
    homePageUrl: "http://${eureka.hostname}/"
    nonSecurePortEnabled: true
    preferIpAddress: false
ryanjbaxter commented 2 years ago

When I run your previous sample you supplied (https://github.com/spring-cloud/spring-cloud-config/issues/2017#issuecomment-997465541) with ./mvnw spring-boot:run -P local

I see both profiles active

2021-12-21 09:26:05.333  INFO 74372 --- [           main] c.o.s.h.f.HpFetcherConfigApplication     : The following profiles are active: awss3,local
AnthonyCavanagh commented 2 years ago

Yes there are two profiles, but it does not run local, All that does is say is I have two profiles. I need a way for it to say run as both profiles

AnthonyCavanagh commented 2 years ago

What I am trying to do is run the config server in the cloud on a ECS, I have a client that runs in the cloud as a ECS and Eureka running as a EC2 on the cloud. The example was so easy. Add the config data to a S3 bucket. Then the client just uses the ServiceId to connect to the Configserver. And that is what I have done and it should work but it wont.

AnthonyCavanagh commented 2 years ago

The problem trying to run Eureka with Spring cloud config, I have 4 applcations. I have eureka I have zuul I have a spring config server which is a client of Eurka and regsiters with it And I have a application which I want to use to connect to the config server by its ServiceId it then downlods from the store config data which includes data such as the path to Eurka so it can register itself.

AnthonyCavanagh commented 2 years ago

There is something that is even more annoying on the client side. Because I am having problems with setting Eureka, I decided leave all the config data in the yml, and just have one item in the repo a simple hello string. The idea being that maybe Eureka should not be added to the config , but other data can. That would at least give me something. Now the following code without using spring cloud config works.

server.port: 8080
spring:
  profiles:
    active: @activatedProperties@
  application:
    name: @artifactId@

# service discovery
eureka:
  client:
    validateCertificates: false
    registerWithEureka: true
    fetchRegistry: true
    healthcheck:
      enabled: true
    serviceUrl:
      defaultZone: "http://${eureka.server.host}:8761/eureka/"
  instance:
    statusPageUrl: "http://${eureka.hostname}/actuator"
    healthCheckUrl: "http://${eureka.hostname}/actuator/health"
    homePageUrl: "http://${eureka.hostname}/"
    nonSecurePortEnabled: true
    preferIpAddress: false

But when I add config server

server.port: 8080

spring:
  profiles:
    active: @activatedProperties@
  application:
    name: @artifactId@
  config:
    import: "configserver:"
  cloud:
    config:
      fail-fast: true
      enabled: true
      #uri: http://169.254.172.2:8080
      discovery:
        enabled: true
        serviceId: HP-FETCHER-CONFIG-SERVICE

eureka:
  client:
    validateCertificates: false
    registerWithEureka: true
    fetchRegistry: true
    healthcheck:
      enabled: true
    serviceUrl:
      defaultZone: "http://${eureka.server.host}:8761/eureka/"
  instance:
    statusPageUrl: "http://${eureka.hostname}/actuator"
    healthCheckUrl: "http://${eureka.hostname}/actuator/health"
    homePageUrl: "http://${eureka.hostname}/"
    nonSecurePortEnabled: true
    preferIpAddress: false

It throws an exception

23:27:50.411 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.IllegalArgumentException: Not enough variable values available to expand 'eureka.server.host'
        at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.java:370)

I thought the idea was that it would look local first, before it looked to config server. So I cant even get it working to test if it would just give me a simple string.

AnthonyCavanagh commented 2 years ago

This is what I have at the moment this is my client application.yml

server.port: 8080

spring:
  profiles:
    active: @activatedProperties@
  application:
    name: @artifactId@
  config:
    import: "configserver:"
  cloud:
    config:
      fail-fast: true
      enabled: true
      #uri: http://169.254.172.2:8080
      discovery:
        enabled: true
        serviceId: HP-FETCHER-CONFIG-SERVICE

But does the service Id work the same way as a uri. With a url you have a http://localhost:8060 and then @artifactId@ is the name of my application call client and @activatedProperties@ is the profile call it dev

so it will be realized as http://localhost:8060 /client/dev and in the and in my S3 repo I have config data client-dev.yml

But if I am using ServiceId to call the data, will it still be looking for client-dev.yml. I think this may be the real problem.

AnthonyCavanagh commented 2 years ago

Back to my original question it looks as if spring.cloud.config.awsS3 can only work as its own profile, and is not designed to be portable between environments