restcurlcloud-foundrycf-cli

Cloud Foundry Task - Call REST API from the service instance


Is there a way to call a REST API of the service instance running in Cloud Foundry from the Cloud Foundry Task (command).

For instance, I have a Spring Boot app instance called my-rest-app running in PCF. It has an endpoint /sayHello. Using cf run-task my-test-app curl /sayHello?


Solution

  • You can do this but you'd need to tell the task how to locate the given service.

    Your task runs in a separate container from the application, so you can't use http://localhost:$PORT because they are separate. That means you need to obtain the URL to your application for the task. You can do that in a couple of different ways.

    When Accessing a Different App

    To access a different app (i.e. app1's task -> app 2), you need to pass in the URL for the target app. That can be done through an environment variable or a bound service.

    The task and service share the same environment variables and bound services, so just set an env variable on your app or bind a service to your app and you'll have access to that through the task.

    For example:

    cf set-env my-cool-app URL 'http://www.example.com/'
    cf restart my-cool-app
    cf run-task my-cool-app 'curl "$URL"'
    

    Make sure to properly quote the last command so that $URL is not evaluated locally.

    or

    cf cups my-service -p url  # populate the url when prompted
    cf bind-service my-cool-app my-service
    cf restart my-cool-app
    cf run-task my-cool-app 'curl $(echo "$VCAP_SERVICES" | jq -r ".[\"user-provided\"][0].credentials.url")'
    

    This is a little more complicated but pulls the URL to request out of the VCAP_SERVICES env variable which is where the bound service information lives.

    When Accessing the Same App

    If you are trying to access the same app (i.e. app1's task -> app1), you can pull the URL from VCAP_APPLICATION so you don't need an env variable or bound service.

    For example:

    cf run-task my-cool-app 'curl https://$(echo "$VCAP_APPLICATION" | jq -r ".uris[0]")'
    

    This will pull the first URI that's mapped to the app. If you have multiple routes bound to your app, you may need to adjust this to pick a different URI. This should include a route path if your route has a path associated with it.

    If you need to access /actuator/health or a specific subpath under the app, you can just append that onto the end of the URI fetched here.