> For the complete documentation index, see [llms.txt](https://docs.graph.build/EGeX4aTAJLlpg9Hh8kfl/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.graph.build/EGeX4aTAJLlpg9Hh8kfl/getting-started-tutorial/installation/aws/create-and-run-ecs-services-and-tasks-v3.2-onwards.md).

# Create & Run ECS Services & Tasks v3.2 Onwards

Graph.Build AWS Marketplace products are Docker images which run on Amazon ECS.

You can find all the docker images on the [Graph.Build page at the Amazon ECR Public Gallery](https://gallery.ecr.aws/graph.build).

{% hint style="info" %}
**Prefer CloudFormation Quick Create** for production. Current Marketplace/BYOL templates already set Studio ECS hardening (`StopTimeout: 120`, deployment `maximumPercent: 100` / `minimumHealthyPercent: 0`, ALB health checks on `/health`, EFS at `/app/studio-data`, `RDF4J_HOME=/app/studio-data/semantic`, and `ECS_CONTAINER_STOP_TIMEOUT=120s` on the EC2 host). Use the example task definition below only when assembling a stack by hand.
{% endhint %}

{% hint style="warning" %}
**Studio Node is dual-process (Node + embedded RDF4J).** Never run more than one task against the same store volume. Allow at least 120 seconds on stop (`stopTimeout` / `ECS_CONTAINER_STOP_TIMEOUT`). Point ALB health checks at `/health` for Studio UI and Studio Node — not `/` (licence middleware can return HTTP 555 on `/`).
{% endhint %}

1. Create an Amazon S3 bucket for Graph.Build to use for graph model staging. You will need this in the Task Definition below. We recommend creating a bucket that follows a format similar to: `s3://graph-build-{AWS_ACCOUNT_ID}`
2. Create / Update an `ecsTask` and `ecsTaskExecution` role in IAM. The roles should include access to S3 (specifically the bucket from step 1) for graph model staging and configuration, CloudWatch for logging, and Neptune to be able to write to Amazon Neptune.
3. Using the below example Task Definition as a guide, create a Task Definition that suits your requirements, referring to the [Amazon ECS documentation](https://docs.aws.amazon.com/ecs/) to see how to create Task Definitions, and run ECS services and tasks.

See the below example ECS Task Definition to run a Graph.Build stack, replacing these values as necessary.

> **Warning:** AWS Service Connect is not currently supported for setting the `STUDIO_NODE_HOST` environment variable

| Name                      | Description                                                                   | Example                                                          |
| ------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `GRAPH_DATABASE_ENDPOINT` | Target graph database endpoint for writing to.                                | `https://xxx.cluster-xxxe.us-east-1.neptune.amazonaws.com:8182/` |
| `AWS_REGION`              | The AWS region in which the stack will run                                    | `us-east-1`                                                      |
| `AWS_ACCOUNT_ID`          | Your 12 digit AWS account ID                                                  | `XXXXXXXXXXXX`                                                   |
| `STUDIO_NODE_HOST`        | The hostname or IP address of the EC2 instance being used by this ECS cluster | `145.225.875.888`                                                |

The containers included to run in this example ECS Task Definition are:

* Studio Node
* Studio UI
* Semi Structured Transformer x1
* SQL Transformer x1
* Graph Writer x1

When you create the **ECS service**, also set:

* `desiredCount`: `1`
* `deploymentConfiguration.maximumPercent`: `100`
* `deploymentConfiguration.minimumHealthyPercent`: `0`
* `healthCheckGracePeriodSeconds`: `600`
* Target group health checks: `/health` on UI and Node

On the EC2 host, add to `/etc/ecs/ecs.config`:

```
ECS_CONTAINER_STOP_TIMEOUT=120s
```

```json
{
    "family": "graphbuild-full-stack",
    "containerDefinitions": [
        {
            "name": "graph-writer",
            "image": "public.ecr.aws/graph.build/graph-writer:latest",
            "cpu": 512,
            "memory": 1024,
            "portMappings": [{"name": "graph-writer-8080-tcp", "containerPort": 8080, "hostPort": 9610, "protocol": "tcp"}],
            "essential": true,
            "environment": [
                {"name": "GRAPH_DATABASE_TYPE", "value": "neptune-sparql"},
                {"name": "TRANSFORMER_RUN_STANDALONE", "value": "true"},
                {"name": "GRAPH_DATABASE_ENDPOINT", "value": "https://{GRAPH_DATABASE_ENDPOINT}:8182/sparql"},
                {"name": "DELETE_SOURCE", "value": "true"}
            ],
            "logConfiguration": {"logDriver": "awslogs", "options": {"awslogs-group": "/ecs/graphbuild-stack", "awslogs-create-group": "true", "awslogs-region": "{AWS_REGION}", "awslogs-stream-prefix": "ecs"}}
        },
        {
            "name": "semi-structured-transformer",
            "image": "public.ecr.aws/graph.build/semi-structured-transformer:latest",
            "cpu": 512,
            "memory": 2048,
            "portMappings": [{"name": "semi-structured-8080-tcp", "containerPort": 8080, "hostPort": 9603, "protocol": "tcp"}],
            "essential": true,
            "environment": [
                {"name": "TRANSFORMER_DIRECTORY", "value": "s3://graph-build-{AWS_ACCOUNT_ID}/ss/"},
                {"name": "TRANSFORMER_RUN_STANDALONE", "value": "true"},
                {"name": "RECORD_PROVO", "value": "false"},
                {"name": "PROPERTY_GRAPH_MODE", "value": "false"},
                {"name": "MAX_CSV_ROWS", "value": "50000"}
            ],
            "logConfiguration": {"logDriver": "awslogs", "options": {"awslogs-group": "/ecs/graphbuild-stack", "awslogs-create-group": "true", "awslogs-region": "{AWS_REGION}", "awslogs-stream-prefix": "ecs"}}
        },
        {
            "name": "sql-transformer",
            "image": "public.ecr.aws/graph.build/sql-transformer:latest",
            "cpu": 512,
            "memory": 2048,
            "portMappings": [{"name": "sql-transformer-8080-tcp", "containerPort": 8080, "hostPort": 9602, "protocol": "tcp"}],
            "essential": true,
            "environment": [
                {"name": "TRANSFORMER_DIRECTORY", "value": "s3://graph-build-{AWS_ACCOUNT_ID}/sql/"},
                {"name": "TRANSFORMER_RUN_STANDALONE", "value": "true"},
                {"name": "RECORD_PROVO", "value": "false"},
                {"name": "PROPERTY_GRAPH_MODE", "value": "false"}
            ],
            "logConfiguration": {"logDriver": "awslogs", "options": {"awslogs-group": "/ecs/graphbuild-stack", "awslogs-create-group": "true", "awslogs-region": "{AWS_REGION}", "awslogs-stream-prefix": "ecs"}}
        },
        {
            "name": "studio-ui",
            "image": "public.ecr.aws/graph.build/studio-ui:latest",
            "cpu": 512,
            "memory": 1024,
            "portMappings": [{"name": "mapping-ui-3000-tcp", "containerPort": 80, "hostPort": 9600, "protocol": "tcp"}],
            "essential": true,
            "environment": [{"name": "REACT_APP_NODEAPP_HOST", "value": "http://{STUDIO_NODE_HOST}:9601"}],
            "logConfiguration": {"logDriver": "awslogs", "options": {"awslogs-group": "/ecs/graphbuild-stack", "awslogs-create-group": "true", "awslogs-region": "{AWS_REGION}", "awslogs-stream-prefix": "ecs"}}
        },
        {
            "name": "studio-node",
            "image": "public.ecr.aws/graph.build/studio-node:latest",
            "cpu": 2048,
            "memory": 8192,
            "stopTimeout": 120,
            "portMappings": [{"name": "mapping-ui-node-js-8080-tcp", "containerPort": 9601, "hostPort": 9601, "protocol": "tcp"}],
            "essential": true,
            "environment": [
                {"name": "NODE_ENV", "value": "production"},
                {"name": "PORT", "value": "9601"},
                {"name": "DATABASE_CLIENT", "value": "better-sqlite3"},
                {"name": "RDF4J_HOME", "value": "/app/studio-data/semantic"},
                {"name": "RDF4J_JVM_OPTS", "value": "-XX:MaxRAMPercentage=50.0"}
            ],
            "mountPoints": [{"sourceVolume": "studio-data", "containerPath": "/app/studio-data", "readOnly": false}],
            "logConfiguration": {"logDriver": "awslogs", "options": {"awslogs-group": "/ecs/graphbuild-stack", "awslogs-create-group": "true", "awslogs-region": "{AWS_REGION}", "awslogs-stream-prefix": "ecs"}}
        }
    ],
    "taskRoleArn": "arn:aws:iam::{AWS_ACCOUNT_ID}:role/graphBuildECSRole",
    "executionRoleArn": "arn:aws:iam::{AWS_ACCOUNT_ID}:role/graphBuildECSRole",
    "volumes": [{"name": "studio-data", "host": {"sourcePath": "/app/studio-data"}}],
    "requiresCompatibilities": ["EC2"]
}
```
