Services

Providing Instance Type in Services

When creating a service, we can set the instance type by including it under the resources key in the following YAML format:

resources:
    instanceTypeId: 43

To obtain a list of all available instances along with their corresponding instanceTypeId, we can use the following command with the entity type depending on the type of service we are creating:

For web-app or shiny type services:

peak tenants list-instance-options --entity-type webapp

For api type services:

peak tenants list-instance-options --entity-type api-deployment

Session Stickiness in Services (Not required for API type services)

By default, session stickiness is disabled (false). You can activate session stickiness by setting the sessionStickiness parameter to true.

Session stickiness ensures that each user’s requests are consistently directed to a particular server. This feature is especially valuable for stateful applications like web applications that rely on server-stored session data.

Note that employing session stickiness may lead to unpredictable behavior and is not recommended if you plan to scale your application.

Creating a service

We can create a service by providing payload like following.

# service.yaml

body:
  name: my-service
  title: New service
  description: This is a new service
  serviceType: web-app
  imageDetails:
    imageId: 100
    versionId: 100
  resources:
    instanceTypeId: 43
  parameters:
    env:
      param1: value1
      param2: value2
    secrets:
      - secret1
      - secret2
  sessionStickiness: true
  entrypoint: |
    python
    app.py
  healthCheckURL: /health

We can use the following command to create a service:

peak services create path/to/create_service.yaml -v path/to/service_params.yaml

Alternatively, we can also use the create command without having the need to provide a yaml. This is possible using the command line options or optionally combining them with yaml template, with the command line options taking precedence.

peak services create --name my-service --description some-description --title my-title --service-type web-app --image-id <image-id> --version-id <version-id> --instance-type-id 43 --env arg1=value1 --env arg2=value2 --secrets secret1 --secrets secret2 --entrypoint "python\napp.py" --healthCheckURL "/health" --session-stickiness

Above command will generate the following json body:

{
    "name": "my-service",
    "title": "my-title",
    "description": "some-description",
    "serviceType": "web-app",
    "imageDetails": {
        "imageId": "<image-id>",
        "versionId": "<version-id>"
    },
    "resources": {
        "instanceTypeId": 43
    },
    "parameters": {
        "env": {
            "arg1": "value1",
            "arg2": "value2"
        },
        "secrets": ["secret1", "secret2"]
    },
    "entrypoint": "python\napp.py",
    "healthCheckURL": "/health",
    "sessionStickiness": true
}

Updating a service

When updating the service, it will trigger a redeployment only under specific conditions. Redeployment is triggered if you make changes to any of the following parameters: imageId, versionId, instanceTypeId, env, secrets, entrypoint, healthCheckURL or sessionStickiness. However, only modifying the title or description will not trigger a redeployment.

With the help of this operation, we can just update the required fields (except name and serviceType) and keep the rest of the fields as it is.

We can update the service by providing service id and payload like following.

# service.yaml

body:
  title: Updated service
  description: This is an updated service
  imageDetails:
    imageId: 200
    versionId: 200
  resources:
    instanceTypeId: 43
  parameters:
    env:
      param1: value1
      param2: value2
    secrets:
      - secret1
      - secret2
  sessionStickiness: true
  entrypoint: |
    python
    app.py
  healthCheckURL: /health

We can use the following command to update a service:

peak services update -v path/to/service_params.yaml <service-id> path/to/update_service.yaml

Alternatively, we can also use the update command without having the need to provide a yaml. This is possible using the command line options or optionally combining them with yaml template, with the command line options taking precedence.

peak services update <service-id> --description some-description --title my-title --image-id <image-id> --version-id <version-id> --instance-type-id 43 --env arg1=value1 --env arg2=value2 --secrets secret1 --secrets secret2 --entrypoint "python\napp.py" --healthCheckURL "/health" --session-stickiness

Above command will generate the following json body:

{
    "title": "my-title",
    "description": "some-description",
    "imageDetails": {
        "imageId": "<image-id>",
        "versionId": "<version-id>"
    },
    "resources": {
        "instanceTypeId": 43
    },
    "parameters": {
        "env": {
            "arg1": "value1",
            "arg2": "value2"
        },
        "secrets": ["secret1", "secret2"]
    },
    "entrypoint": "python\napp.py",
    "healthCheckURL": "/health",
    "sessionStickiness": true
}

Using the create-or-update operation

The create-or-update operation facilitates the creation of a new service if it doesn’t exist or updates an existing service based on its name field.

If the service is being updated, it will trigger a redeployment only under specific conditions. Redeployment is triggered if you make changes to any of the following parameters: imageId, versionId, instanceTypeId, env, secrets, entrypoint, healthCheckURL or sessionStickiness. However, only modifying the title or description will not trigger a redeployment.

Consider the following example for creating a service:

# service.yaml

body:
  name: my-service
  title: New service
  description: This is a new service
  serviceType: web-app
  imageDetails:
    imageId: 100
    versionId: 100
  resources:
    instanceTypeId: 43
  parameters:
    env:
      param1: value1
      param2: value2
    secrets:
      - secret1
      - secret2
  sessionStickiness: true
  entrypoint: |
    python
    app.py
  healthCheckURL: /health
peak services create-or-update -v path/to/service_params.yaml <service-id> path/to/create_or_update_service.yaml --image-id 3 --name my-service

Now we could update the service created with above command as follows:

# service_params.yaml

imageId: 2
versionId: 2
# service.yaml
body:
    title: Updated service
    description: This is an updated service
    imageDetails:
        imageId: {{ imageId }}
        versionId: {{ versionId }}
    resources:
        instanceTypeId: 43
    parameters:
        env:
            arg1: value1
            arg2: value2
        secrets:
            - secret1
            - secret2
    entrypoint: "python\napp.py"
    healthCheckURL: "/health"
    sessionStickiness: true
peak services create-or-update -v path/to/service_params.yaml <service-id> path/to/service.yaml --image-id 3 --name my-service --instance-type-id 43 --session-stickiness

In the above example, the imageId will be overwritten by the command line options and the final service body will look like:

{
    "title": "Updated service",
    "description": "This is an updated service",
    "imageDetails": {
        "imageId": 3,
        "versionId": 2
    },
    "resources": {
        "instanceTypeId": 43
    },
    "parameters": {
        "env": {
            "arg1": "value1",
            "arg2": "value2"
        },
        "secrets": ["secret1", "secret2"]
    },
    "entrypoint": "python\napp.py",
    "healthCheckURL": "/health",
    "sessionStickiness": true
}

Launching Web App and Shiny type Services

We can obtain the application URL for a service by using the describe command.

We can use the following command to describe a service:

peak services describe <service-id>

The output of the describe command will contain the service details along with the application URL which can be used to launch web-app or shiny type services.

Testing API type Services

We can test an API type service to verify it’s health and if it is working.

For testing an API type service, we need to provide the service name, http method, and optionally the path and payload to test the service. The payload is optional and is only required for post, put and patch methods.

The payload can be provided either though a yaml file or through the command line options.

We can use the following command to test an API type service:

peak services test <service-name> path/to/test_service.yaml --http-method get --path /health
# test_service.yaml

body:
  httpMethod: post
  path: /
  payload: # Payload to test the API type service. This is a sample payload.
    id: 1
    name: test

Alternatively, we can also use the test command without having the need to provide a yaml.

peak services test <service-name> --http-method get --path /health --payload "{'key': 'value'}"