Semantic Relationship

How to create Semantic Dependencies and Triggers at Bluebricks

Semantic Triggers™ are preemptive connections that allow blueprints to maintain a loosely coupled architecture by leveraging each other's outputs, creating a flexible network of interconnected resources.

There are two types of semantic connections:

  1. Semantic Dependencies – Connections defined within bricks.json using the Data object to ensure parameter continuity.

  2. Semantic Triggers (coming soon) – Connections defined at the graph level enable parameter continuity between two or more separate blueprints.

How to Create Semantic Dependencies

Users can create Semantic Dependencies by setting the output of one blueprint as the input for another.

For example, consider a blueprint, named server, which includes an AWS VPC blueprint and an AWS EC2 blueprint. In this setup, the goal is for the VPC ID generated in the AWS VPC blueprint to be used as an input for the AWS EC2 blueprint, thereby establishing a Semantic Dependency:

server bricks.json
{
    "name": "server",
    "description": "basic blueprint",
    "version": "1.0.0",
    "author": "[email protected]",
    "packages": [
        {
            "name": "@acme/aws_single_ec2",
            "id": "aws_single_ec2_0d538",
            "version": "1.1.1",
            "props": {
                "instance_type": {
                    "value": "Props.aws_single_ec2_instance_type"
                },
                "key_name": {
                    "value": "Props.aws_single_ec2_key_name"
                },
                "monitoring": {
                    "value": "Props.aws_single_ec2_monitoring"
                },
                "name": {
                    "value": "Props.aws_single_ec2_name"
                },
                "subnet_id": {
                    "value": "Props.aws_single_ec2_subnet_id"
                },
                "tags": {
                    "value": "Props.aws_single_ec2_tags"
                },
                "vpc_security_group_ids": {
                    "value": "Props.aws_single_ec2_vpc_security_group_ids"
                }
            }
        },
        {
            "name": "@acme/aws_vpc",
            "id": "aws_vpc_ef440",
            "version": "1.2.1",
            "props": {
                "cidr": {
                    "value": "Props.aws_vpc_cidr"
                },
                "enable_nat_gateway": {
                    "value": "Props.aws_vpc_enable_nat_gateway"
                },
                "enable_vpn_gateway": {
                    "value": "Props.aws_vpc_enable_vpn_gateway"
                },
                "name": {
                    "value": "Props.aws_vpc_name"
                },
                "region": {
                    "value": "Props.aws_vpc_region"
                },
                "single_nat_gateway": {
                    "value": "Props.aws_vpc_single_nat_gateway"
                },
                "tags": {
                    "value": "Props.aws_vpc_tags"
                }
            }
        }
    ],
    "props": {
       ...
    },
    "outs": {
      ...
    }
}

To achieve this, we’ll set the subnet_id and vpc_security_group_ids properties of @acme/aws_single_ec2 to use the output of @acme/aws_vpc. This creates a Semantic Dependency, ensuring the EC2 instance is provisioned with the correct subnet and security group from the VPC.

We’ll use the bp get command to fetch outputs from the aws_vpc blueprint:

~> bricks bp get outs @acme/aws_vpc
`@acme/aws_vpc`:

  NAME                VALUE   TYPE     DESCRIPTION

  private_subnets             list     List of IDs of private subnets
  public_subnets              list     List of IDs of public subnets
  security_group_id           string   The ID of the security group created by default on VPC creation
  vpc_cidr_block              string   The CIDR block of the VPC
  vpc_id                      string   The ID of the VPC

Then, we'll assign the required output key as the value in the aws_single_ec2 blueprint, under the relevant property:

{
    ...
    "packages": [
        {
            "name": "@acme/aws_single_ec2",
            "id": "aws_single_ec2_0d538",
            "version": "1.1.1",
            "props": {
                ...
                "vpc_security_group_ids": {
                    "value": "Data.aws_vpc_ef440.security_group_id"
                }
            }
        },
        {
            "name": "@acme/aws_vpc",
            "id": "aws_vpc_ef440",
            "version": "1.2.1",
            "props": {
                ...
            }
        }
    ],
    ...
}

Since outputs are collected at runtime in a Data object, we’ll assign the value property using the Data object. This involves referencing the ID of the blueprint that generates the output, followed by the specific output key.

Data.aws_vpc_ef440.security_group_id
^        ^                     ^
Object   Source Blueprint ID   Output Key  

Remember! The value property content is an expr-lang statement, allowing users to manipulate the content as needed.

For example, the expression "'PREFIX_' + Props.name" concatenates the static string "PREFIX_" with the value of the name property at runtime.

Another example is "Data.aws_vpc_ef440.private_subnets[0]", which selects the first item in the private_subnets list at runtime.

How to Create Semantic Triggers™

Semantic Triggers are in the testing phase and will be released by December 2024.

Last updated

Was this helpful?