> For the complete documentation index, see [llms.txt](https://docs.bluerock.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bluerock.io/deployment-guides/aws-deployments/aws-deployment-using-terraform-template.md).

# AWS Deployment Using Terraform Template

### High-Level Architecture Overview

This section provides a conceptual overview of how the BlueRock instance is deployed on AWS EC2 and how its core components interact.

#### End-to-End Flow

Deployment scripts are executed from a user's desktop or client environment where AWS CLI is configured. The script uses AWS APIs to provision the required AWS Resources and deploy the BlueRock instance.

#### BlueRock EC2 Architecture Components

#### Architecture Diagram

<figure><img src="https://1983702018-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCNnVnPvaRpvlLmPT6IAN%2Fuploads%2FbPwG0NtXGKy8voVA6BYh%2FChatGPT%20Image%20Feb%203%2C%202026%2C%2003_18_20%20PM.png?alt=media&amp;token=52fa223f-68a0-48ed-9e64-459c20240128" alt=""><figcaption></figcaption></figure>

#### **BlueRock EC2 Architecture Components**

A typical BlueRock Secure MCP Server EC2 deployment consists of the following AWS Resources/Services:

<table data-search="false"><thead><tr><th width="316.65625">AWS Resources/Services</th><th>Description</th></tr></thead><tbody><tr><td><strong>Virtual Private Cloud (VPC)</strong></td><td>Provides an isolated networking environment in AWS where all BlueRock deployment resources are created.</td></tr><tr><td><strong>Amazon VPC Gateway</strong></td><td>Enables controlled inbound and outbound internet access for resources deployed inside the VPC.</td></tr><tr><td><strong>Amazon EC2 (BlueRock Node)</strong></td><td>Runs the BlueRock MCP Server using a hardened BlueRock AMI and hosts all runtime services.</td></tr><tr><td><strong>Amazon Elastic Block Store (EBS)</strong></td><td>Provides persistent block storage attached to the EC2 instance for operating system and application data.</td></tr><tr><td><strong>Amazon S3 (BlueRock Config)</strong></td><td>Stores BlueRock configuration files such as <code>config.toml</code> that are retrieved by the BlueRock control plane during runtime.</td></tr><tr><td><strong>AWS Identity and Access Management (IAM) Role</strong></td><td>Grants the EC2 instance permission to access required AWS services such as Amazon S3 and Amazon CloudWatch.</td></tr><tr><td><strong>Amazon CloudWatc</strong></td><td>Receives telemetry and monitoring data generated by the BlueRock MCP Server.</td></tr><tr><td><strong>Amazon CloudWatch Logs</strong></td><td>Stores runtime logs and security events generated by the BlueRock MCP Server for analysis and auditing.</td></tr><tr><td><strong>User / Administrator</strong></td><td>Manages and monitors the BlueRock deployment through AWS services such as CloudWatch and AWS Systems Manager (SSM).</td></tr></tbody></table>

***

#### Deployment types

BlueRock EC2 deployments support multiple deployment modes depending on networking and telemetry requirements:

<table data-header-hidden><thead><tr><th width="176.95703125">Deployment Mode</th><th>Description</th></tr></thead><tbody><tr><td><strong>Private</strong></td><td>Deploys a single BlueRock EC2 instance into a private subnet, with outbound access via a NAT Gateway and management access enabled through AWS Systems Manager (SSM).</td></tr><tr><td><strong>Public</strong></td><td>Deploys a single BlueRock EC2 instance into a public subnet, allowing management access through SSH (if configured) and AWS Systems Manager (SSM).</td></tr></tbody></table>

***

### Supported AMI Distributions

BlueRock Secure MCP Server supports the following Linux distributions. Each distribution has a corresponding AMI with a specific kernel version:

| **Name**              | **Kernel Version** | **AMI NAME**                                |
| --------------------- | ------------------ | ------------------------------------------- |
| **Amazon Linux 2023** | 6.12.89            | bluerock-release-26-23-1-amzlnx2023-6.12.89 |
| **Ubuntu 24.04**      | 6.12.89            | bluerock-release-26-23-1-ubuntu2404-6.12.89 |

Note: The AMI name includes the **BlueRock release version**, **Linux distribution**, and **Kernel version**, allowing users to identify compatibility directly from the AMI name

***

### &#x20;Prerequisites

#### AWS Requirements

* Active AWS account
* API key credentials configured in the local environment
* AWS CLI should be installed, and key credentials should be configured

#### Required Packages

The BlueRock Deployment Package for EC2 is provided by BlueRock as part of customer onboarding.\
This package includes Terraform infrastructure-as-code (IaC) scripts required to deploy the BlueRock Secure MCP Server on AWS EC2.

#### Deployment Method

The following tools must be installed and configured in the local environment before running the deployment:

* **Terraform**\
  Required to execute the BlueRock Terraform deployment scripts.

  Terraform installation guide:\
  <https://developer.hashicorp.com/terraform/downloads>
* **AWS CLI**\
  Required for authentication, resource validation, and post-deployment verification.

  AWS CLI installation and configuration guide:\
  <https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html>

```shellscript
Configuration file location: ~/.aws/credentials

File Content:
AWS_ACCESS_KEY_ID=[your_access_key]
AWS_SECRET_ACCESS_KEY=[your_secret_key]
AWS_SESSION_TOKEN=[your_session_token]
```

#### AWS Permissions Required

**User permissions:** The user executing the deployment script requires permissions to create the following AWS objects:

* VPC, Subnets, Internet Gateway, Route Tables
* EC2 instance
* Security Group
* IAM Profile
* S3 bucket

{% hint style="info" icon="notes-sticky" %}
**Note:**

The IAM instance profile required for the BlueRock instance is automatically created by the deployment script.&#x20;
{% endhint %}

***

### Deployment Package Overview

#### Download and Extract Package

Download the BlueRock deployment package and extract it in your local environment.

```bash
terraform.tar.gz

$ tar -xzf terraform.tar.gz

$ ls -l
cloudformation.tar.gz
terraform/
terraform.tar.gz

```

***

### **Directory Structure**

#### Public Deployment

```shellscript
terraform/
└── ec2/
        ├── al2023/
        │   └── PublicDeployment/
        │       ├── README.md
        │       ├── main.tf
        │       ├── outputs.tf
        │       ├── terraform.tfvars.example
        │       └── variables.tf
        └── ubuntu/
            └── PublicDeployment/
                ├── README.md
                ├── main.tf
                ├── outputs.tf
                ├── terraform.tfvars.example
                └── variables.tf
```

#### Private/ External OTEL Deployment&#x20;

```shellscript
terraform/
└── ec2/
        ├── al2023/
        │   └── ExternalOtel/
        │       ├── README.md
        │       ├── main.tf
        │       ├── outputs.tf
        │       ├── terraform.tfvars.example
        │       ├── user_data.sh.tpl
        │       └── variables.tf
        └── ubuntu/
            └── ExternalOtel/
                ├── README.md
                ├── main.tf
                ├── outputs.tf
                ├── terraform.tfvars.example
                ├── user_data.sh.tpl
                └── variables.tf

```

***

### Terraform Deployment

#### Configuration Parameters

Navigate to the Terraform deployment directory, copy the example variables file, and update the deployment parameters by editing the Terraform variables file:

```shellscript
## Amazon Linux:
$ cd terraform/ec2/al2023/PublicDeployment

## Ubuntu:
$ cd terraform/ec2/ubuntu/PublicDeployment

$ cp terraform.tfvars.example terraform.tfvars
$ vi terraform.tfvars
```

### Parameter Reference

The following table details the variables and parameters for the provided Terraform configuration block.

| **Parameter**                        | **Type** | **Description**                                                                                                                   |
| ------------------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `region`                             | String   | The AWS region where the resources will be provisioned (e.g., `us-east-1`).                                                       |
| `prefix`                             | String   | A naming prefix applied to all created resources to easily identify them (e.g., `bluerock-ec2`).                                  |
| `allow_ip`                           | String   | The CIDR block permitted to access the instance, typically used for restricting inbound SSH or API traffic (e.g., `10.0.0.0/32`). |
| `node_instance_type`                 | String   | The AWS EC2 instance size/type to provision for the BlueRock node (e.g., `t3.xlarge`).                                            |
| `sample_host_name`                   | String   | The designated hostname for the deployed instance.                                                                                |
| `ssh_key_name`                       | String   | The name of an existing AWS EC2 Key Pair used to authenticate SSH access to the instance.                                         |
| `ami_id`                             | String   | The specific Amazon Machine Image (AMI) ID used to launch the instance.                                                           |
| `existing_vpc_id`                    | String   | The ID of an existing AWS VPC. If left empty (`""`), the Terraform module will create a new VPC.                                  |
| `existing_subnet_id`                 | String   | The ID of an existing AWS Subnet. If left empty (`""`), the Terraform module will create a new Subnet.                            |
| `enable_external_otel`               | Boolean  | Master toggle (`true` or `false`) to enable or disable the external OpenTelemetry (OTel) configuration.                           |
| `existing_policy_bucket_name`        | String   | *(Optional)* The name of an existing S3 bucket used for storing policies.                                                         |
| `existing_telemetry_log_group_name`  | String   | *(Optional)* The name of an existing AWS CloudWatch Log Group for routing telemetry logs.                                         |
| `existing_telemetry_log_stream_name` | String   | *(Optional)* The name of an existing AWS CloudWatch Log Stream within the designated Log Group.                                   |

{% hint style="info" icon="notes-sticky" %}
**Note:**

* Deployment on existing VPC: Provide both vpc\_id and subnet\_id values
* Deployment on new VPC: Leave both values empty (null)
  {% endhint %}

### Running the Deployment Script

Navigate to the Terraform deployment directory, initialize Terraform, review the execution plan, and apply the configuration to provision the BlueRock Secure MCP Server:

```shellscript
$ cd terraform/ec2/al2023/PublicDeployment
$ terraform init
$ terraform plan
$ terraform apply
```

**Capture outputs**

The deployment will output critical information including:

* EC2 instance Public IP
* S3 bucket name
* CloudWatch log group name

```bash
## Expected Output:
s3_bucket_name      = "bluerock-ec2-policy-bucket"
s3_bucket_url       = "https://bluerock-ec2-policy-bucket.s3.us-east-1.amazonaws.com"
instance_id         = "i-0x0x0x0x0x0x00000"
instance_public_ip  = "00.000.00.00"
instance_private_ip = "00.0.0.00"
vpc_id              = "vpc-0x0x0x0x0x0x00000"
subnet_id           = "subnet-0x0x0x0x0x0x00000"
log_group_name      = "bluerock-ec2-telemetry"
log_stream_name     = "bluerock-ec2-stream"
```

***

### Post-Deployment Validation

This section verifies that the BlueRock Secure MCP Server has been deployed successfully and is functioning as expected.

#### Check Bluerock Instance

Check the instance status to confirm that the EC2 instance is running and has a public IP address assigned (for public deployments):

<pre class="language-shellscript"><code class="lang-shellscript">aws ec2 describe-instances\ --filters "Name=tag:Name,Values=bluerock*"

Output:
<strong>{
</strong>  "Reservations": [
    {
      "Instances": [
        {
          "InstanceId": "i-09d31837043f8b71d",
          "InstanceType": "t3.xlarge",
          "State": {
            "Code": 16,
            "Name": "running"
          },
          "PublicIpAddress": "3.85.120.175",
          "PrivateIpAddress": "172.31.134.24",
          "Placement": {
            "AvailabilityZone": "us-east-1b"
          },
          "Tags": [
            {
              "Key": "Name",
              "Value": "bluerock-ec2"
            }
          ]
        }
      ]
    }
  ]
}

</code></pre>

#### Check Instance Access

**SSH Access**&#x20;

Check instance access to confirm SSH connectivity for public deployments by running the appropriate command for the selected AMI:

```shellscript
Amazon Linux:
$ ssh -i /path/to/key.pem ec2-user@<PUBLIC_IP>

Ubuntu:
$ ssh -i /path/to/key.pem ubuntu@<PUBLIC_IP>
```

#### Verify BlueRock Control Plane Service

Verify that the BlueRock Control Plane service is running by checking that the `bluerockd.service` service is in the **active (running)** state.

```shellscript
$ sudo systemctl status bluerockd.service

● bluerockd.service - BlueRock Daemon
     Loaded: loaded (/usr/lib/systemd/system/bluerockd.service; enabled; preset: enabled)
    Drop-In: /usr/lib/systemd/system/bluerockd.service.d
             └─10-containerd.conf
     Active: active (running) since Thu 2026-07-02 12:35:22 UTC; 55ms ago
       Docs: https://bluerock.io/
   Main PID: 2955 (bluerockd)
      Tasks: 8 (limit: 18781)
     Memory: 3.3M (peak: 3.3M)
        CPU: 52ms
     CGroup: /system.slice/bluerockd.service
             └─2955 /opt/bluerock/bin/bluerockd --config=/etc/bluerock/bluerockd.toml --socket=/run/bluerock/sensor.sock --stdout

Jul 02 12:35:22 ip-172-31-29-210 systemd[1]: Started bluerockd.service - BlueRock Daemon.
Jul 02 12:35:22 ip-172-31-29-210 bluerockd[2955]: 2026-07-02T12:35:22.612626065Z  INFO bluerockd: bluerockd/src/main.rs:54: Config: /etc/bluerock/bluerockd.toml
Jul 02 12:35:22 ip-172-31-29-210 bluerockd[2955]: 2026-07-02T12:35:22.613193913Z  INFO bluerockd: bluerockd/src/main.rs:95: OTEL event file: /var/log/bluerockd/otel-events.log (from config)

```

`bluerockd.service` works on the configuration of `bluerockd.toml` file that resides at  `/etc/bluerock/bluerockd.toml` in the BlueRock VM instance.&#x20;

{% code title="bluerockd.toml" lineNumbers="true" %}

```toml
[runtime]
metrics_timer = 1800
state_dir = "/var/lib/bluerockd/"

[policy]
public_key = "s3://${policy_bucket}/bluerock_pub_key.pem"
poll_period = 100

[policy.source]
location   = "s3://${policy_bucket}/"
policy     = "policy.json"
policy_sig = "policy.json.sig"

[policy.source.transport]
auth_method = "default"
region      = "${region}"

[policy.engine]
augment_events = true

[otlp]
file = "/var/log/bluerockd/otel-events.log"

[otlp.http]
url = "http://$SERVICE_PRIVATE_IP:4318/"
```

{% endcode %}

It is created automatically with Terraform and has the following parameters.

| **Parameter**                         | **Type** | **Description**                                                                                                         |
| ------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| `runtime.metrics_timer`               | Integer  | The interval (in seconds) at which metrics are collected or emitted (e.g., `1800`).                                     |
| `runtime.state_dir`                   | String   | The directory path where the daemon maintains its internal state files (e.g., `/var/lib/bluerockd/`).                   |
| `policy.public_key`                   | String   | The URI location (e.g., an S3 path) of the public key used to cryptographically verify the policy file's signature.     |
| `policy.poll_period`                  | Integer  | The frequency (in seconds) at which the system polls the source location for policy updates.                            |
| `policy.source.location`              | String   | The base URI or storage bucket path where the policy files are hosted.                                                  |
| `policy.source.policy`                | String   | The filename of the primary JSON policy document (e.g., `policy.json`).                                                 |
| `policy.source.policy_sig`            | String   | The filename of the cryptographic signature corresponding to the policy document (e.g., `policy.json.sig`).             |
| `policy.source.transport.auth_method` | String   | The authentication strategy used to access the policy source (e.g., `default` to use instance IAM roles/profiles).      |
| `policy.source.transport.region`      | String   | The cloud provider region where the policy source bucket is located.                                                    |
| `policy.engine.augment_events`        | Boolean  | Controls whether evaluated policy events are augmented with additional system context before being logged or forwarded. |
| `otlp.file`                           | String   | The absolute file path where local OpenTelemetry (OTel) events and logs are written.                                    |
| `otlp.http.url`                       | String   | The HTTP endpoint URL used to export OTel telemetry data to a collector or backend service.                             |

{% hint style="info" %}
**Note:**\
To update the `${policy_bucket}` change or update the prefix param `${var.prefix}-policybucket` in `terraform.tfvars` .
{% endhint %}

### **Check OTEL Collector**

1. Locate the OTEL config file:

   ```shellscript
   $ cd /opt/bluerock/otel

   $ ls

   otel-config.yaml
   ```
2. Edit the `otel-config.yaml` file based on the requirements.
3. Enable the otel service

   ```shellscript
   $ sudo systemctl enable otelcol.service
   ```
4. Start the otel service

   ```shellscript
   $ sudo systemctl start otelcol.service
   ```
5. Check the status of the otel service

   ```shell
   $ sudo systemctl status otelcol.service --no-pager -l
   ● otelcol.service - OpenTelemetry Collector (Bluerock)
        Loaded: loaded (/etc/systemd/system/otelcol.service; enabled; preset: enabled)
        Active: active (running) since Fri 2026-07-03 03:15:22 UTC; 7h ago
          Docs: https://opentelemetry.io/docs/collector/
      Main PID: 3227 (aws-otel-collec)
         Tasks: 9 (limit: 18800)
        Memory: 19.9M (peak: 21.7M)
           CPU: 19.917s
        CGroup: /system.slice/otelcol.service
                └─3227 /opt/aws/aws-otel-collector/bin/aws-otel-collector --config=/opt/bluerock/otel/otel-config.yaml
   Jul 03 03:15:22 ip-172-31-29-175 run-otelcol.sh[3227]: 2026-07-03T03:15:22.324Z        debug        builders/builders.go:24        Stable component.        {"resource": {"service.instance.id": "27df2ba6-b766-4dc7-9b5b-c80a5956c45c", "service.name": "aws-otel-collector", "service.version": "v0.44.0"}, "otelcol.component.id": "otlp", "otelcol.component.kind": "receiver", "otelcol.signal": "logs"}
   Jul 03 03:15:22 ip-172-31-29-175 run-otelcol.sh[3227]: 2026-07-03T03:15:22.324Z        debug        Logger core does not support injecting component attributes        {"resource": {"service.instance.id": "27df2ba6-b766-4dc7-9b5b-c80a5956c45c", "service.name": "aws-otel-collector", "service.version": "v0.44.0"}, "otelcol.component.id": "otlp", "otelcol.component.kind": "receiver", "otelcol.signal": "logs"}
   ```

#### Verify Telemetry Events in AWS CloudWatch&#x20;

**Check CloudWatch logs:**

1. Navigate to the **CloudWatch Console**

<figure><img src="https://1983702018-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCNnVnPvaRpvlLmPT6IAN%2Fuploads%2FIa8Rqo7hFIN1APJ0nthb%2FScreenshot%202026-02-05%20at%206.17.23%E2%80%AFPM.png?alt=media&amp;token=00fdbad6-9b8a-40fd-b748-52780c5ca33e" alt=""><figcaption></figcaption></figure>

2. Go to **Log Groups**

<figure><img src="https://1983702018-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCNnVnPvaRpvlLmPT6IAN%2Fuploads%2FOdfFZRM8iAI2qonyF2eh%2FScreenshot%202026-02-05%20at%206.19.28%E2%80%AFPM.png?alt=media&amp;token=78f1dd5c-76b4-48f4-aadc-e18ed2cf1f6d" alt=""><figcaption></figcaption></figure>

3. Find the BlueRock Log Group

<figure><img src="https://1983702018-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCNnVnPvaRpvlLmPT6IAN%2Fuploads%2FBGSi0UH8FmGk1F1bf00t%2Fimage.png?alt=media&amp;token=b24baf90-db46-4757-9249-9943793fa71e" alt=""><figcaption></figcaption></figure>

3. **Verify:**

* Log entries are present
* Events originate from the EC2 instance
* Timestamps align with instance startup activity

<figure><img src="https://1983702018-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCNnVnPvaRpvlLmPT6IAN%2Fuploads%2Fb8J10aMmAtAdodHMMsA2%2Fimage.png?alt=media&amp;token=a5e9297e-c3f6-4f66-95e5-7400da1dc187" alt=""><figcaption></figcaption></figure>

Expected logs include runtime events emitted by the BlueRock Secure MCP Server.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.bluerock.io/deployment-guides/aws-deployments/aws-deployment-using-terraform-template.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
