# Automation setup instruction

{% hint style="info" %}
Automation is currently available for workloads with type **`Deployment`**, **`DaemonSet`**, **`StatefulSet`**, **`CronJob`** and **`Job`**.&#x20;
{% endhint %}

{% hint style="info" %}
PerfectScale **does not support** automating workloads that use the **OnDelete update strategy**. The OnDelete strategy requires manual intervention to update pods, which falls outside the scope of PerfectScale's automated optimization capabilities.
{% endhint %}

## Step 1: Install PerfectScale Automation Agent

{% hint style="warning" %}
When deploying the **PerfectScale Automation Agent** in a **GKE Private Cluster**, you need to create an additional firewall rule. This enables the Control Plane address range to communicate with the Cluster Pod IPv4 address range on port 8443. If the webhook call fails, see the [troubleshooting guide](https://docs.perfectscale.io/2.0-self-hosted-or-perfectscale-documentation/automation-troubleshooting#failed-to-call-webhook).
{% endhint %}

Deploy the PerfectScale automation agent. In order to install the PerfectScale automation agent, run the following commands:

```
helm repo add perfectscale https://perfectscale-io.github.io --force-update
```

and

```
helm upgrade --install -n perfectscale psc-autoscaler \
      --set secret.create=false \
      --set settings.psUrl=<https://api-{your-web-ui-url}> \
      --set settings.telemetryUrl=<https://api-{{your-web-ui-url}}/psc-telemetry> \
      perfectscale/psc-autoscaler
```

{% hint style="info" %}
If taints and tolerations are defined in the node pool, you must include them in the command too, so it will appear like this:

```
helm upgrade --install -n perfectscale psc-autoscaler \
      --set tolerations[0].key=node_pool \
      --set tolerations[0].operator=Equal \
      --set tolerations[0].value=tooling \
      --set secret.create=false \
      perfectscale/psc-autoscaler
```

{% endhint %}

{% hint style="warning" %}
If you utilize CI/CD tools with auto-sync, ensure to review the additional configuration steps. [automation-with-gitops](https://docs.perfectscale.io/2.0-self-hosted-or-perfectscale-documentation/enable-automation/automation-with-gitops "mention")
{% endhint %}

{% hint style="info" %}
Follow the [**troubleshooting**](https://docs.perfectscale.io/2.0-self-hosted-or-perfectscale-documentation/enable-automation/automation-troubleshooting) instructions provided, or [**contact support**](https://join.slack.com/t/perfectscalecommunity/shared_invite/zt-1tu9teu9e-Z9tGt4LpNI8tUC3j8obcmQ) if you encounter any issues.
{% endhint %}

### Verify Automation Agent Installation

To test and confirm that the Automation Agent was installed successfully, run the following command:

```
helm test psc-autoscaler -n perfectscale --logs
```

### Disabling Webhook for Specific Namespaces

Once the autoscaler is installed, all pods in the cluster go through the admission webhook. You can exclude specific namespaces from this process by disabling the webhook for them. For example:

<pre><code>helm upgrade --install -n perfectscale psc-autoscaler perfectscale/psc-autoscaler \
--set secret.create=false \
<a data-footnote-ref href="#user-content-fn-1">--set 'settings.excludedNamespaces={kube-system,ns_to_exclude1,ns_to_exclude2}'</a>
</code></pre>

## Step 2: Create Custom Resource (CR)&#x20;

After the installation of the automation agent, it is important to create a **cluster automation configuration**, as this step **is mandatory:**&#x20;

```yaml
apiVersion: perfectscale.io/v1
kind: ClusterAutomationConfig
metadata:
  name: cluster-automation-config
spec:
  automation:
    operational:
      stopAllAutomation: false # Global kill switch for automation (default: false)
      cleanupAllAutomation: false # Stops automation and reverts all changes, restoring original resource specifications and settings
```

{% hint style="info" %}
Automation is only enabled in configurations where automationMode for the workload type is set to "Enabled". This can be configured in the `ClusterAutomationConfig`, `NamespaceAutomationConfig`, or `WorkloadAutomationConfig`.

**Example**:

```yaml
apiVersion: perfectscale.io/v1
kind: ClusterAutomationConfig
metadata:
  name: cluster-automation-config
spec:
  automation:
    operational:
      stopAllAutomation: false # Global kill switch for automation (default: false)
      cleanupAllAutomation: false # Stops automation and reverts all changes, restoring original resource specifications and settings  
    workloadTypes:
      Deployment:
        operational:
          automationMode: "Enabled" # Enables automation for the workloads with a specific type in the cluster/namespace
```

This configuration enables automation for all workloads in a cluster with **type: Deployment**. Learn more about enabling automation for particular workload types [in a cluster](#cluster-level-configuration), [specific namespace](#namespace-level-configuration), or [specific workloads](#workload-level-configuration).
{% endhint %}

{% hint style="info" %}
**Only one cluster-level automation configuration can be applied per cluster**. To prevent errors, PerfectScale recommends using consistent naming for cluster-level configurations within the same cluster. This ensures that a new configuration will override the previous one without causing any conflicts.
{% endhint %}

To help you quickly start using PerfectScale Automation and streamline the optimization process, we provide pre-built Custom Resources (CRs) focused on desired optimization goals. You can easily implement the following CRs and customize them if needed.

{% hint style="info" %}
PerfectScale recommends you start with the cluster [cost-saving automation configuration](#recommended-adoption-path).&#x20;

:point\_right: Explore more configuration examples at our [GitHub](https://github.com/perfectscale-io/perfectscale-io.github.io/tree/main/charts/psc-autoscaler/examples).
{% endhint %}

## :zap: <mark style="color:green;">Recommended adoption path</mark>

To minimize waste and achieve optimal savings, we recommend starting with a simple, cluster-level automation focused on cost reduction.

**Create** a YAML file with the recommended cluster-level automation configuration using the following template:

```yaml
apiVersion: perfectscale.io/v1
kind: ClusterAutomationConfig
metadata:
  name: cluster-automation-config
spec:
  automation:
    operational:
      stopAllAutomation: false # Global kill switch for automation (default: false)
      cleanupAllAutomation: false # Stops automation and reverts all changes, restoring original resource specifications and settings  
    workloadTypes:
      Deployment:
        operational:
          automationMode: "Enabled" # Enables automation for the workloads with a specific type in the cluster/namespace
          restrictions:
      DaemonSet:
        operational:
          automationMode: "Enabled" # Enables automation for the workloads with a specific type in the cluster/namespace
          restrictions:
```

**Apply** the created configuration by running the following command (where `cluster-automation-config.yaml` - the name of your file created in the previous step):

```
kubectl apply -f cluster-automation-config.yaml
```

### Combining cost-savings and performance improvement configuration  <a href="#example-2-combining-automated-cost-savings-and-performance-improvement" id="example-2-combining-automated-cost-savings-and-performance-improvement"></a>

The following example of a Cluster-level automation configuration allows you to automate the optimization of the entire cluster, enhancing its performance while maintaining optimal costs.

**Create** a YAML file with the cluster-level automation configuration using the following template:

```yaml
apiVersion: perfectscale.io/v1
kind: ClusterAutomationConfig
metadata:
  name: cluster-automation-config
spec:
  automation:
    operational:
      stopAllAutomation: false # Global kill switch for automation (default: false)
      cleanupAllAutomation: false # Stops automation and reverts all changes, restoring original resource specifications and settings  
    workloadTypes:
      Deployment:
        operational:
          automationMode: "Enabled" # Enables automation for the workloads with a specific type in the cluster/namespace
          restrictions:
            workloadMinWasteUSDPerMonth: 5 # Activates automation only if monthly waste exceeds a set threshold (for example, $5)
            cpuManagement:
              request:
                increaseEnabled: true # Allows PerfectScale Automation to increase CPU requests if the performance risks are observed
                decreaseEnabled: true # Allows PerfectScale Automation to decrease CPU requests to minimize waste
              limit:
                keepLimit: true # Automation will maintain a non-zero CPU limit and will not set the value to zero
            memoryManagement:
              request:
                increaseEnabled: true # Allows PerfectScale Automation to increase Memory requests if the performance risks are observed
                decreaseEnabled: true # Allows PerfectScale Automation to decrease Memory requests to minimize waste
              limit:
                increaseEnabled: true # Allows PerfectScale Automation to increase Memory limit if the performance risks are observed
                decreaseEnabled: true # Allows PerfectScale Automation to decrease Memory limit
      DaemonSet:
        operational:
          automationMode: "Enabled" # Enables automation for the workloads with a specific type in the cluster/namespace
          restrictions:
            workloadMinWasteUSDPerMonth: 5 # Activates automation only if monthly waste exceeds a set threshold (for example, $5)
            cpuManagement:
              request:
                increaseEnabled: true # Allows PerfectScale Automation to increase CPU requests if the performance risks are observed
                decreaseEnabled: true # Allows PerfectScale Automation to decrease CPU requests to minimize waste
              limit:
                keepLimit: true # Automation will maintain a non-zero CPU limit and will not set the value to zero
            memoryManagement:
              request:
                increaseEnabled: true # Allows PerfectScale Automation to increase Memory requests if the performance risks are observed
                decreaseEnabled: true # Allows PerfectScale Automation to decrease Memory requests to minimize waste
              limit:
                increaseEnabled: true # Allows PerfectScale Automation to increase Memory limit if the performance risks are observed
                decreaseEnabled: true # Allows PerfectScale Automation to decrease Memory limit
```

**Apply** the created configuration by running the following command (where `cluster-automation-config.yaml` - the name of your file created in the previous step):

```
kubectl apply -f cluster-automation-config.yaml
```

Let's explore additional examples of automation configurations that offer more granular and flexible control over Automation:

* [How to include a cluster, namespace, or workload in the Automation configuration](https://docs.perfectscale.io/2.0-self-hosted-or-perfectscale-documentation/enable-automation/including-a-cluster-namespace-or-workload-to-the-automation)
* [How to exclude a namespace or workload from the Automation configuration](https://docs.perfectscale.io/2.0-self-hosted-or-perfectscale-documentation/enable-automation/excluding-a-namespace-or-workload-from-the-automation)

### Automation configuration defaults <a href="#automation-configuration-defaults" id="automation-configuration-defaults"></a>

Some automation configuration settings have predefined defaults. If you don’t specify a value, PerfectScale will automatically apply the default for that field. Below is the list of configurations and their default values.

<table data-header-hidden><thead><tr><th>Config</th><th>Default</th></tr></thead><tbody><tr><td>stopAllAutomation</td><td>false</td></tr><tr><td>cleanupAllAutomation</td><td>false</td></tr><tr><td>automationMode</td><td>Enabled</td></tr><tr><td>workloadLabelSelectors</td><td>nil</td></tr><tr><td>wasteMaxAutomationFrequency</td><td><p>Deployment: 30m</p><p>Rollout: 30m</p><p>CronJob: 30m</p><p>Job: 30m</p><p>DaemonSet: 4h</p><p>StatefulSet: 24h</p></td></tr><tr><td>fixResiliencyMaxAutomationFrequency</td><td>30m</td></tr><tr><td>maintenanceWindowIgnoredForResiliency</td><td>false</td></tr><tr><td>maintenanceWindowIgnoredMinResiliencyLevel</td><td>""</td></tr><tr><td>maintenanceWindow</td><td><p></p><pre><code>monday:
  - "00:00-23:59"
tuesday:
  - "00:00-23:59"
wednesday:
  - "00:00-23:59"
thursday:
  - "00:00-23:59"
friday:
  - "00:00-23:59"
saturday:
  - "00:00-23:59"
sunday:
  - "00:00-23:59"
</code></pre></td></tr><tr><td>workloadMinWasteUSDPerMonth</td><td>5</td></tr><tr><td>cpuManagement</td><td><p><strong>request:</strong></p><p>IncreaseEnabled: false </p><p>DecreaseEnabled: true </p><p>MinimumCores: -1 // no limit </p><p>MaximumCores: -1 // no limit </p><p></p><p><strong>limit:</strong> </p><p>KeepLimit: true</p></td></tr><tr><td>memoryManagement</td><td><p><strong>request:</strong></p><p>IncreaseEnabled: false </p><p>DecreaseEnabled: true </p><p>MinimumGiB: -1 // no limit </p><p>MaximumGib: -1 // no limit </p><p></p><p><strong>limit:</strong> </p><p>IncreaseEnabled: false </p><p>DecreaseEnabled: false </p><p>MinimumGiB: -1 // no limit </p><p>MaximumGib: -1 // no limit </p><p></p><p><strong>maxMemoryIncreaseIterations:</strong> </p><p>Daily: 3 </p><p>Weekly: 6</p></td></tr></tbody></table>

[^1]: Exclude a Namespace
