# Install on Amazon ECS

The Steadybit Agent can be installed on **Amazon Elastic Container Service**.

## Amazon ECS with EC2

### Compatibility

[extension-host](https://hub.steadybit.com/extension/com.steadybit.extension_host) and [extension-container](https://hub.steadybit.com/extension/com.steadybit.extension_container) needs to run in privileged mode and network mode `host` is required for the extensions.

### Installation

#### Pre-requisites

* You need to have an ECS cluster running with at least one EC2 instance.
* You need to know the (private) Subnet-IDs where you want to place the agent and extension tasks.
* The security group used by the ec2 instances need to allow inbound traffic to the `extension-host` and `extension-container` (ports 8085 and 8086) as they are running as daemon service using the host network.

#### Step-By-Step Guide

1. Copy the required Files

* [steadybit-agent.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-agent.json)
* [steadybit-agent-role-trust-policy.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-agent-role-trust-policy.json)
* [steadybit-agent-role-permissions.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-agent-role-permissions.json)
* [steadybit-extension-host.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-extension-host.json)
* [steadybit-extension-container.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-extension-container.json)
* [steadybit-extension-http.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-extension-http.json)
* [steadybit-extension-aws.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-extension-aws.json)
* [steadybit-extension-aws-role-permissions.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-extension-aws-role-permissions.json)

2. The agent needs some permissions to be able to look up extensions running in the cluster. Create a IAM role for the agent task with the following permissions:

   ```bash
   aws iam create-role --role-name steadybit-agent-task-role --assume-role-policy-document file://steadybit-agent-role-trust-policy.json
   aws iam put-role-policy --role-name steadybit-agent-task-role --policy-name steadybit-agent-extension-lookup --policy-document file://steadybit-agent-role-permissions.json
   ```
3. If you like to install the `extension-aws` you need to create a new IAM role with the following permissions. Please have a look at the [extension documentation](https://github.com/steadybit/extension-aws?tab=readme-ov-file#required-permissions-policies) for the latest list of required permissions.

   ```bash
   aws iam create-role --role-name steadybit-extension-aws-task-role --assume-role-policy-document file://steadybit-agent-role-trust-policy.json
   aws iam put-role-policy --role-name steadybit-extension-aws-task-role --policy-name steadybit-extension-aws --policy-document file://steadybit-extension-aws-role-permissions.json
   ```
4. Replace all placeholders in the JSON files with your values. All placeholders are prefixed with `MY-`. Take care, the placeholders are used multiple times in the JSON files.
   * `MY-AGENT-KEY`: Your agent key
   * `MY-CLUSTER-NAME`: The name of your ECS cluster
   * `MY-PLATFORM-URL`: The URL of your Steadybit platform, for SaaS use `https://platform.steadybit.com`
   * `MY-REGION`: The AWS region where your ECS cluster is running
   * `MY-ACCOUNT`: The AWS account ID
5. Register the Task Definitions

   ```bash
   aws ecs register-task-definition --cli-input-json file://steadybit-agent.json 
   aws ecs register-task-definition --cli-input-json file://steadybit-extension-host.json
   aws ecs register-task-definition --cli-input-json file://steadybit-extension-container.json
   aws ecs register-task-definition --cli-input-json file://steadybit-extension-http.json
   aws ecs register-task-definition --cli-input-json file://steadybit-extension-aws.json
   ```
6. Create the Services

   * **Agent** - please replace the cluster-name, subnet-ids, and security-group-id with your values. The security group needs to allow outbound traffic to the Steadybit platform and to the extensions (ports 8080-8099).

   ```bash
   aws ecs create-service \
    --cluster MY-CLUSTER \
    --service-name steadybit-agent \
    --task-definition steadybit-agent \
    --propagate-tags TASK_DEFINITION \
    --desired-count 1 \
    --deployment-configuration maximumPercent=101,minimumHealthyPercent=0 \
    --tags key=steadybit.com/discovery-disabled,value=true \
    --network-configuration '{"awsvpcConfiguration": {"subnets": ["MY-SUBNET-1", "MY-SUBNET-2", "MY-SUBNET-3"], "securityGroups": ["MY-SECURITY-GROUP-ID"], "assignPublicIp": "DISABLED"}}'
   ```

   * **Extension Host** - please replace the cluster-name. The extension will use the host network strategy and use the security groupd and subnets of your ec2 instances.

   ```bash
   aws ecs create-service \
    --cluster MY-CLUSTER \
    --service-name steadybit-extension-host \
    --task-definition steadybit-extension-host \
    --propagate-tags TASK_DEFINITION \
    --launch-type EC2 \
    --tags key=steadybit.com/discovery-disabled,value=true \
    --scheduling-strategy DAEMON
   ```

   * **Extension Container** - please replace the cluster-name. The extension will use the host network strategy and use the security groupd and subnets of your ec2 instances.

   ```bash
   aws ecs create-service \
    --cluster MY-CLUSTER \
    --service-name steadybit-extension-container \
    --task-definition steadybit-extension-container \
    --propagate-tags TASK_DEFINITION \
    --launch-type EC2 \
    --tags key=steadybit.com/discovery-disabled,value=true \
    --scheduling-strategy DAEMON
   ```

   * **Extension HTTP** - please replace the cluster-name, subnet-ids, and security-group-id with your values. The security group needs to allow inbound traffic to the extension (port 8085) and outbound traffic to all ports/destination you want to reach out with the http checks implemented in the extension.

   ```bash
   aws ecs create-service \
    --cluster MY-CLUSTER \
    --service-name steadybit-extension-http \
    --task-definition steadybit-extension-http \
    --propagate-tags TASK_DEFINITION \
    --desired-count 1 \
    --deployment-configuration maximumPercent=101,minimumHealthyPercent=0 \
    --tags key=steadybit.com/discovery-disabled,value=true \
    --network-configuration '{"awsvpcConfiguration": {"subnets": ["MY-SUBNET-1", "MY-SUBNET-2", "MY-SUBNET-3"], "securityGroups": ["MY-SECURITY-GROUP-ID"], "assignPublicIp": "DISABLED"}}'    
   ```

   * **Extension AWS** - please replace the cluster-name, subnet-ids, and security-group-id with your values. The security group needs to allow inbound traffic to the extension (port 8085)

   ```bash
   aws ecs create-service \
    --cluster MY-CLUSTER \
    --service-name steadybit-extension-aws \
    --task-definition steadybit-extension-aws \
    --propagate-tags TASK_DEFINITION \
    --desired-count 1 \
    --deployment-configuration maximumPercent=101,minimumHealthyPercent=0 \
    --tags key=steadybit.com/discovery-disabled,value=true \
    --network-configuration '{"awsvpcConfiguration": {"subnets": ["MY-SUBNET-1", "MY-SUBNET-2", "MY-SUBNET-3"], "securityGroups": ["MY-SECURITY-GROUP-ID"], "assignPublicIp": "DISABLED"}}'    
   ```

## Amazon ECS with Fargate

### Compatibility

The agent and most of the extensions can be run as an ECS service in Fargate.

However, [extension-host](https://hub.steadybit.com/extension/com.steadybit.extension_host) and [extension-container](https://hub.steadybit.com/extension/com.steadybit.extension_container) are not compatible with AWS Fargate because they require access to the underlying compute instance which is not possible with Fargate.

[extension-aws](https://hub.steadybit.com/extension/com.steadybit.extension_aws) can also be used with Fargate and offers some alternative actions to discover and attack ECS resources.

### Installation

1. Copy the required Files

* [steadybit-agent-fargate.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-agent-fargate.json)
* [steadybit-agent-role-trust-policy.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-agent-role-trust-policy.json)
* [steadybit-agent-role-permissions.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-agent-role-permissions.json)
* [steadybit-extension-http-fargate.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-extension-http-fargate.json)
* [steadybit-extension-aws-fargate.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-extension-aws-fargate.json)
* [steadybit-extension-aws-role-permissions.json](https://github.com/steadybit/docs-public/blob/main/install-and-configure/install-agent/ecs/steadybit-extension-aws-role-permissions.json)

2. The agent needs some permissions to be able to look up extensions running in the cluster. Create a IAM role for the agent task with the following permissions:

   ```bash
   aws iam create-role --role-name steadybit-agent-task-role --assume-role-policy-document file://steadybit-agent-role-trust-policy.json
   aws iam put-role-policy --role-name steadybit-agent-task-role --policy-name steadybit-agent-extension-lookup --policy-document file://steadybit-agent-role-permissions.json
   ```
3. Fargate tasks needs a task execution role to be able to write logs. If you don't already have an existing role, you can create one via:

   ```bash
   aws iam create-role --role-name steadybit-agent-task-execution-role --assume-role-policy-document file://steadybit-agent-role-trust-policy.json
   aws iam attach-role-policy --role-name steadybit-agent-task-execution-role --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
   aws iam attach-role-policy --role-name steadybit-agent-task-execution-role --policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
   ```
4. If you like to install the `extension-aws` you need to create a new IAM role with the following permissions. Please have a look at the [extension documentation](https://github.com/steadybit/extension-aws?tab=readme-ov-file#required-permissions-policies) for the latest list of required permissions.

   ```bash
   aws iam create-role --role-name steadybit-extension-aws-task-role --assume-role-policy-document file://steadybit-agent-role-trust-policy.json
   aws iam put-role-policy --role-name steadybit-extension-aws-task-role --policy-name steadybit-extension-aws --policy-document file://steadybit-extension-aws-role-permissions.json
   ```
5. Replace all placeholders in the JSON files with your values. All placeholders are prefixed with `MY-`. Take care, the placeholders are used multiple times in the JSON files.
   * `MY-AGENT-KEY`: Your agent key
   * `MY-CLUSTER-NAME`: The name of your ECS cluster
   * `MY-PLATFORM-URL`: The URL of your Steadybit platform, for SaaS use `https://platform.steadybit.com`
   * `MY-REGION`: The AWS region where your ECS cluster is running
   * `MY-ACCOUNT`: The AWS account ID
6. Register the Task Definitions

   ```bash
   aws ecs register-task-definition --cli-input-json file://steadybit-agent-fargate.json 
   aws ecs register-task-definition --cli-input-json file://steadybit-extension-http-fargate.json
   aws ecs register-task-definition --cli-input-json file://steadybit-extension-aws-fargate.json
   ```
7. Create the Services

   * **Agent** - please replace the cluster-name, subnet-ids, and security-group-id with your values. The security group needs to allow outbound traffic to the Steadybit platform and to the extensions (ports 8080-8099).

   ```bash
   aws ecs create-service \
    --cluster MY-CLUSTER \
    --service-name steadybit-agent \
    --task-definition steadybit-agent-fargate \
    --propagate-tags TASK_DEFINITION \
    --launch-type FARGATE \
    --desired-count 1 \
    --deployment-configuration maximumPercent=101,minimumHealthyPercent=0 \
    --tags key=steadybit.com/discovery-disabled,value=true \
    --network-configuration '{"awsvpcConfiguration": {"subnets": ["MY-SUBNET-1", "MY-SUBNET-2", "MY-SUBNET-3"], "securityGroups": ["MY-SECURITY-GROUP-ID"], "assignPublicIp": "DISABLED"}}'
   ```

   * **Extension HTTP** - please replace the cluster-name, subnet-ids, and security-group-id with your values. The security group needs to allow inbound traffic to the extension (port 8085) and outbound traffic to all ports/destination you want to reach out with the http checks implemented in the extension.

   ```bash
   aws ecs create-service \
    --cluster MY-CLUSTER \
    --service-name steadybit-extension-http \
    --task-definition steadybit-extension-http \
    --propagate-tags TASK_DEFINITION \
    --launch-type FARGATE \
    --desired-count 1 \
    --deployment-configuration maximumPercent=101,minimumHealthyPercent=0 \
    --tags key=steadybit.com/discovery-disabled,value=true \
    --network-configuration '{"awsvpcConfiguration": {"subnets": ["MY-SUBNET-1", "MY-SUBNET-2", "MY-SUBNET-3"], "securityGroups": ["MY-SECURITY-GROUP-ID"], "assignPublicIp": "DISABLED"}}'    
   ```

   * **Extension AWS** - please replace the cluster-name, subnet-ids, and security-group-id with your values. The security group needs to allow inbound traffic to the extension (port 8085)

   ```bash
   aws ecs create-service \
    --cluster MY-CLUSTER \
    --service-name steadybit-extension-aws \
    --task-definition steadybit-extension-aws \
    --propagate-tags TASK_DEFINITION \
    --launch-type FARGATE \
    --desired-count 1 \
    --deployment-configuration maximumPercent=101,minimumHealthyPercent=0 \
    --tags key=steadybit.com/discovery-disabled,value=true \
    --network-configuration '{"awsvpcConfiguration": {"subnets": ["MY-SUBNET-1", "MY-SUBNET-2", "MY-SUBNET-3"], "securityGroups": ["MY-SECURITY-GROUP-ID"], "assignPublicIp": "DISABLED"}}'    
   ```

## FAQ

* **Q:** How can I update the agent/extensions and force pulling a new image version when using `latest`?
  * **A:** `aws ecs update-service --cluster <your-cluster> --service <your-service> --force-new-deployment`
* **Q:** Can I shell into the agent/extension tasks?
  * **A:** Yes, with ECS Exec, details can be found [here](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html), short summary below:
    * You need to allow update your service to allow it, e.g.: `aws ecs update-service --service steadybit-agent --cluster <your-cluster> --enable-execute-command`
    * The task role needs the following permissions:
      * `ssmmessages:CreateControlChannel`
      * `ssmmessages:CreateDataChannel`
      * `ssmmessages:OpenControlChannel`
      * `ssmmessages:OpenDataChannel`
    * The task definition needs to include `initProcessEnabled` in the `linuxParameters`, e.g:

      ```json
      {
        "containerDefinitions": [
          {
            "name": "steadybit-agent",
            ...
            "linuxParameters": {
              "initProcessEnabled": true
            }
          }
        ]
      }
      ```
    * After that, you can shell into the agent task with `aws ecs execute-command --cluster <your-cluster> --task <your-task-id> --container <container-name> --interactive --command "/bin/bash"`


---

# 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.steadybit.com/install-and-configure/install-agent/aws-ecs.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.
