# Standardize new service creation

Developers often need to spin up new services for use cases like feature development and architecture processes. Doing this manually can be error-prone and inconsistent across teams. To achieve engineering excellence, it is critical to modernize and standardize this practice; you can use a Cortex Workflow to ensure every new service has best practices built in from the start.

The Workflow in this example streamlines service creation by guiding you through a form to input service information then automatically handling the rest: creating a new repository based on your input, creating an entity in Cortex that includes custom data and a linked repository, and automatically opening a Jira ticket to ensure visibility and tracking.&#x20;

{% hint style="success" %}
Cortex customer Archer saves 24 hours per new service created by using Workflows to automate service creation with best practices built in. [Learn more below](#example-archers-deployment-workflow).
{% endhint %}

## Create a Workflow to standardize new service creation

### Prerequisites

Before getting started:

* Create a [Jira API token](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/) with the `write:issue:jira` permission.
* Your Cortex role must have the [permissions](/configure/settings/managing-users/permissioning.md) `Edit Workflows`, `Execute Workflow runs`, `Configure Scaffolder templates`, and `Execute Scaffolder`.&#x20;
* You should have already configured your version control provider integration with `write` access.
* Make sure you have already [registered your Scaffolder template](/streamline/workflows/scaffolder.md).&#x20;
  * In this example, we use the [cookiecutter-spring-boot repository](https://github.com/cortex-workshops/cookiecutter-spring-boot).

### Step 1: Configure the Workflow basic settings

Follow the steps in the documentation to [create a Workflow](/streamline/workflows/create.md) and configure its basic settings.

### Step 2: Add blocks to the Workflow

Add the following blocks to the Workflow:

<details>

<summary>User input</summary>

This block contains the three fields that a user is prompted to fill out when the Workflow is run.

1. Click **+** in the center of the page. In the block library modal, select the **User input** block.
2. In the side panel, enter a name and unique slug for the block.
3. Click **+Add user input**. Configure the input:
   1. **Name**: Enter `Service Name`.
   2. **Key**: Enter `service-name`.
   3. **Description**: Optionally enter a description for this input.
   4. **Required**: Toggle this setting on if you want to require your users to enter input for this field.
   5. **Type**: Select `Text`.
   6. Click **Add input**.
4. Click **+Add user input** again. Configure the input:
   1. **Name**: Enter `Service Tag`.
   2. **Key**: Enter `service-tag`.
   3. **Description**: Optionally enter a description for this input. In our example, we add a description to ensure that users understand what a Cortex tag is in Cortex:\
      `The Cortex tag is a unique identifier that's used throughout Cortex. Do not use spaces. Example: my-service`
   4. **Required**: Toggle this setting on if you want to require your users to enter input for this field.
      * If you are asking for a unique tag, we recommend setting this field as required.
   5. **Type**: Select `Text`.
   6. Click **Add input**.
5. Click **+Add user input** again. Configure the input:
   1. **Name**: Enter `Incident Process Documented`.
   2. **Key**: Enter `incident-process-documented`.
   3. **Description**: Optionally enter a description for this input. In our example, we add a description to ensure that users understand what this step is asking for:\
      `Has the incident process been submitted to your team lead?`
   4. **Required**: Toggle this setting on if you want to require your users to enter input for this field.
   5. **Type**: Select `Toggle`.
   6. **Default value**: In our example, we set this to `False` to ensure users don't accidentally send a false positive.
   7. Click **Add input**.
6. Click **Save** at the bottom of the side panel.

<div align="left"><figure><img src="/files/VNpk5r8BPZ3f4T8XkO26" alt="The User input step contains three input fields." width="382"><figcaption></figcaption></figure></div>

</details>

<details>

<summary>Scaffolder</summary>

This block creates a new repository in your connected Git integration, using templating to apply the outputs of the User Input step as the project name, app name, and repository name.

1. Click **+** in the center of the page. In the block library modal, select the **Scaffolder** block.
2. In the side panel, enter a name and unique slug for the block.
3. Under **Scaffolder template**, select your template. In this example, we use the `Spring Boot Template`.
4. Select the option to **Create a new repo**.
5. Add override variables. The **Variable** dropdown pulls in all the variables that are able to be overridden in the Git provider and in the Scaffolder template. In this example, we apply the following overrides:
   * **project\_name**: `actions.user-input.outputs.service-name`
     * This overrides it with the output of the "Service name" field from the User Input block earlier in the Workflow.
   * **creator**: `context.initiatedBy.email`&#x20;
     * This overrides it with the email address of the person who initiated the Workflow.
   * **app\_name**: `actions.user-input.outputs.service-name`
     * Like the project\_name override, this one also overrides it with the output of the "Service Name" field from the User Input block.
   * **publisherRepoName**: `actions.user-input.outputs.service-tag`
     * This overrides it with the output of the "Service Tag" field from the User Input block earlier in the Workflow. This ensures that the repo name matches the [Cortex tag](broken://pages/7yhTO4ww5IUAY2GDnu84#cortex-tag).
6. Click **Save** at the bottom of the side panel.

</details>

<details>

<summary>Cortex custom data</summary>

Earlier in the Workflow, the User Input step prompts a user to enter a service name, tag, and to use a toggle to indicate whether the incident process was documented.&#x20;

The **Add custom data for entity** block determines where the user's response (the custom data) is recorded. Running this step results in the output of the `Incident Process Documented` toggle being added to an entity.

1. Click **+** in the center of the page. In the block library modal, select the **Add custom data for entity** block.
2. In the side panel, enter a name and unique slug for the block.
3. Configure the custom data details:
   1. **Entity tag or ID**, use templating to reference the service tag provided by the user during the User Input step: `{{actions.user-input.outputs.service-tag}}`
   2. **Key**: `incident-process-documented`&#x20;
   3. **Value**: `"{{actions.user-input.outputs.incident-process-documented}}"`
4. Click **Save** at the bottom of the side panel.

</details>

<details>

<summary>HTTP request</summary>

### Step 4: Add an HTTP request block

This step creates a Jira ticket for tracking and security review.

1. Click **+** in the center of the page. In the block library modal, select the **Add custom data for entity** block.
2. In the side panel, enter a name and unique slug for the block.
3. Configure the HTTP request:
   1. **HTTP method**: Select `POST`.
   2. **URL**: Enter your Jira API URL.
   3. **Headers**: Include an authorization header and set the value to your Jira token.
   4. **Payload**: In the payload, you can choose the project in Jira where you want the ticket created, and you can include other information such as the title of the Jira ticket (the `summary`) and the description of the ticket (the `content:text`). See [Jira's API documentation](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-post) for more information on formatting the payload. In this example, we include the following payload:

```json
{
  "fields": {
    "project": {
      "key": "SEC"
    },
    "summary": "Entity ready for security review.",
    "description": {
      "type": "doc",
      "version": 1,
      "content": [
        {
          "type": "paragraph",
          "content": [
            {
              "type": "text",
              "text": "New service ready for review."
            }
          ]
        }
      ]
    },
    "issuetype": {
      "name": "Task"
    }
  }
}
```

4. Click **Save** at the bottom of the side panel.&#x20;

</details>

When you are finished adding blocks, click **Save Workflow** at the top of the page.

### Run the Workflow

* In the list of Workflows, locate your new service creation Workflow and click **Run**.
  * You will be redirected to a page showing the Workflow's steps.&#x20;

The following chain of events occur during the run:

<details>

<summary>Workflow run steps</summary>

1. The **User Input** block runs, which pauses the Workflow until the Workflow initiator enters a response.
   1. In this example, we enter `Docs test` as the **Service Name**, `docs-test` as a **Service Tag**, and toggle on the option for **Incident Process Documented**. <br>

      <figure><img src="/files/bYwNs6hKP3DlRYLtMA5y" alt=""><figcaption></figcaption></figure>
2. The **Scaffolder** block runs, which prompts you to configure and run the Spring Boot Template that was selected while [configuring the Scaffolder step](#scaffolder).
   1. Because of the overrides that were configured in the Scaffolder step, the Project Name, App Name, Creator, and Repository fields are pre-filled. The overridden fields cannot be edited unless you select the option to make override fields editable while configuring the Scaffolder block.
   2. During this step, you must also select the organization to create the repository in, include the branch name and a commit message, and choose the visibility of your repo. When you are finished, click **Submit**. A repository will be created in the organization you selected:<br>

      <figure><img src="/files/Ocih94oVlOq4cqmEEmyD" alt=""><figcaption></figcaption></figure>
3. The **Add custom data** block runs. The newly-created entity for the repository now contains the `incident-process-documented` key and value. You can see this in the **Output** tab of the block during the Workflow run, and in the [entity details page](/ingesting-data-into-cortex/entities-overview/entities/details.md) **Custom data & metrics** sidebar link:<br>

   <figure><img src="/files/46W8wxZVN57dLjZ8lRWS" alt=""><figcaption></figcaption></figure>
4. The **HTTP request** block runs. A ticket is created in Jira requesting a review from the security team. The title and description were set automatically based on the payload provided while [configuring the HTTP request step](#http-request):

   <figure><img src="/files/th2g5meZfUxwUiUaY2By" alt=""><figcaption></figcaption></figure>

</details>

## Example: Archer's deployment Workflow

Cortex customer Archer implemented a Workflow combining scaffolding, infrastructure, deployment configuration, and cloud resources into a single process. All new services follow a consistent, repeatable workflow that includes best practices and requirements by default.&#x20;

### Outcome

* Their teams go from concept to deployed service on a Kubernetes cluster in under 3 hours.&#x20;
* They save 24 hours per new service creation.
* They saved an estimated $72,000 across 30+ Workflow runs in 3 months.

### See the case study

Learn more about Archer's process in the case study: [Archer accelerates engineering efficiency with Workflows](https://www.cortex.io/case-studies/archer).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cortex.io/guides/production-readiness/standardize-new-service-creation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
