MakisDSL

Cloud Resources

Complete guide to all cloud resources available in MakisDSL, their configuration options, and provider-specific implementations.

🔗 Overview

MakisDSL provides six core resource types that abstract common cloud infrastructure patterns. Each resource type maps to equivalent services across AWS, Azure, and GCP:

🔗 Object Storage

Object storage provides scalable blob storage for files, documents, images, and data backups.

Basic Usage

val storage = objectStorage("my-data-bucket")
{
  "my-data-bucket" : {
    "Type" : "AWS::S3::Bucket",
    "Properties" : { }
  }
}
{
  "type" : "Microsoft.Storage/storageAccounts",
  "apiVersion" : "2023-01-01",
  "name" : "my-data-bucket",
  "location" : "[resourceGroup().location]",
  "properties" : {
    "sku" : { "name" : "Standard_LRS" },
    "kind" : "StorageV2",
    "accessTier" : "Hot"
  }
}
{
  "name" : "my-data-bucket",
  "type" : "storage.v1.bucket",
  "properties" : {
    "location" : "US",
    "storageClass" : "STANDARD"
  }
}

Configuration Options

Versioning

Enable object versioning to maintain multiple versions of objects:

val storage = objectStorage("versioned-bucket")
  .withVersioning(true)
{
  "Properties" : {
    "VersioningConfiguration" : {
      "Status" : "Enabled"
    }
  }
}
{
  "properties" : {
    "versioning" : {
      "enabled" : true
    }
  }
}

Public Access Control

Control public access to objects:

val storage = objectStorage("private-bucket")
  .withVersioning(true)
  .withPublicAccess(false)  // Block public access

Use Cases

🔗 Serverless Function

Serverless functions provide event-driven compute without managing servers. They automatically scale and only charge for execution time.

Basic Configuration

val function = serverlessFunction("my-api-handler")
  .withRuntime("nodejs18.x")
  .withHandler("index.handler")
  .withCode("exports.handler = async (event) => { return { statusCode: 200, body: 'Hello World!' }; }")
  .build
{
  "my-api-handler" : {
    "Type" : "AWS::Lambda::Function",
    "Properties" : {
      "Runtime" : "nodejs18.x",
      "Handler" : "index.handler",
      "Code" : {
        "ZipFile" : "exports.handler = async (event) => { return { statusCode: 200, body: 'Hello World!' }; };"
      }
    }
  }
}
{
  "type" : "Microsoft.Web/sites",
  "apiVersion" : "2023-01-01",
  "name" : "my-api-handler",
  "location" : "[resourceGroup().location]",
  "properties" : {
    "kind" : "functionapp",
    "siteConfig" : {
      "appSettings" : [ {
        "name" : "FUNCTIONS_WORKER_RUNTIME",
        "value" : "node"
      }, {
        "name" : "WEBSITE_NODE_DEFAULT_VERSION",
        "value" : "~18"
      } ]
    }
  }
}
{
  "name" : "my-api-handler",
  "type" : "cloudfunctions.v1.function",
  "properties" : {
    "location" : "us-central1",
    "runtime" : "nodejs18",
    "entryPoint" : "index",
    "sourceArchiveUrl" : "gs://my-source-bucket/function.zip"
  }
}

Configuration Options

Runtime Support

Supported runtimes across all providers:

Code Sources

Functions can get code from inline strings or storage references:

// Inline code
val function1 = serverlessFunction("inline-function")
  .withRuntime("nodejs18.x")
  .withHandler("index.handler")
  .withCode("exports.handler = async () => ({ statusCode: 200 })")
  .build

// Code from storage bucket
val bucket = objectStorage("code-bucket")
val function2 = serverlessFunction("stored-function")
  .withRuntime("nodejs18.x")
  .withHandler("index.handler")
  .withCode(bucket.reference)  // Reference to bucket
  .dependsOn(bucket)
  .build

Use Cases

🔗 NoSQL Table

NoSQL tables provide scalable document and key-value storage with automatic scaling and high availability.

Basic Configuration

val table = noSqlTable("my-users-table")
  .withHashKey("userId", "S")
  .build
{
  "my-users-table" : {
    "Type" : "AWS::DynamoDB::Table",
    "Properties" : {
      "KeySchema" : [ {
        "AttributeName" : "userId",
        "KeyType" : "HASH"
      } ],
      "AttributeDefinitions" : [ {
        "AttributeName" : "userId",
        "AttributeType" : "S"
      } ],
      "BillingMode" : "PAY_PER_REQUEST"
    }
  }
}
{
  "type" : "Microsoft.DocumentDB/databaseAccounts",
  "apiVersion" : "2023-04-15",
  "name" : "my-users-table",
  "location" : "[resourceGroup().location]",
  "properties" : {
    "databaseAccountOfferType" : "Standard",
    "consistencyPolicy" : {
      "defaultConsistencyLevel" : "Session"
    },
    "locations" : [ {
      "locationName" : "[resourceGroup().location]",
      "failoverPriority" : 0
    } ]
  }
}
{
  "name" : "my-users-table",
  "type" : "firestore.v1.database",
  "properties" : {
    "location" : "us-central1",
    "type" : "FIRESTORE_NATIVE"
  }
}

Key Types

NoSQL tables support different key types:

Use Cases

🔗 Virtual Network

Virtual networks provide isolated network environments for your cloud resources with full control over IP addressing and routing.

Basic Configuration

val network = virtualNetwork("my-vpc")
{
  "my-vpc" : {
    "Type" : "AWS::EC2::VPC",
    "Properties" : { }
  }
}
{
  "type" : "Microsoft.Network/virtualNetworks",
  "apiVersion" : "2023-04-01",
  "name" : "my-vpc",
  "location" : "[resourceGroup().location]",
  "properties" : {
    "addressSpace" : {
      "addressPrefixes" : [ "10.0.0.0/16" ]
    }
  }
}
{
  "name" : "my-vpc",
  "type" : "compute.v1.network",
  "properties" : {
    "autoCreateSubnetworks" : false,
    "routingConfig" : {
      "routingMode" : "REGIONAL"
    }
  }
}

Use Cases

🔗 Security Group

Security groups act as virtual firewalls that control inbound and outbound traffic to cloud resources.

Basic Configuration

val sg = securityGroup("web-sg")
  .allowInbound("HTTP", 80)
  .allowInbound("HTTPS", 443)
{
  "web-sg" : {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "SecurityGroupIngress" : [ {
        "IpProtocol" : "http",
        "FromPort" : 80,
        "ToPort" : 80,
        "CidrIp" : "0.0.0.0/0"
      }, {
        "IpProtocol" : "https",
        "FromPort" : 443,
        "ToPort" : 443,
        "CidrIp" : "0.0.0.0/0"
      } ]
    }
  }
}
{
  "type" : "Microsoft.Network/networkSecurityGroups",
  "apiVersion" : "2023-04-01",
  "name" : "web-sg",
  "location" : "[resourceGroup().location]",
  "properties" : {
    "securityRules" : [ {
      "name" : "AllowInbound1",
      "properties" : {
        "priority" : 1000,
        "direction" : "Inbound",
        "access" : "Allow",
        "protocol" : "Http",
        "sourcePortRange" : "*",
        "destinationPortRange" : "80",
        "sourceAddressPrefix" : "0.0.0.0/0",
        "destinationAddressPrefix" : "*"
      }
    }, {
      "name" : "AllowInbound2",
      "properties" : {
        "priority" : 1010,
        "direction" : "Inbound",
        "access" : "Allow",
        "protocol" : "Https",
        "sourcePortRange" : "*",
        "destinationPortRange" : "443",
        "sourceAddressPrefix" : "0.0.0.0/0",
        "destinationAddressPrefix" : "*"
      }
    } ]
  }
}
{
  "name" : "web-sg",
  "type" : "compute.v1.firewall",
  "properties" : {
    "direction" : "INGRESS",
    "priority" : 1000,
    "network" : "global/networks/default",
    "allowed" : [ {
      "IPProtocol" : "http",
      "ports" : [ "80" ]
    }, {
      "IPProtocol" : "https",
      "ports" : [ "443" ]
    } ],
    "sourceRanges" : [ "0.0.0.0/0" ]
  }
}

Common Protocols

Use Cases

🔗 Application Load Balancer

Application load balancers distribute incoming traffic across multiple targets for high availability and fault tolerance.

Basic Configuration

val function = serverlessFunction("api-handler")
  .withRuntime("nodejs18.x")
  .withHandler("index.handler")
  .build

val alb = applicationLoadBalancer("web-alb")
  .withTargets(function)
{
  "web-alb" : {
    "Type" : "AWS::ElasticLoadBalancingV2::LoadBalancer",
    "Properties" : {
      "Targets" : [ "api-handler" ]
    }
  }
}
{
  "type" : "Microsoft.Network/loadBalancers",
  "apiVersion" : "2023-04-01",
  "name" : "web-alb",
  "location" : "[resourceGroup().location]",
  "properties" : {
    "sku" : { "name" : "Standard" },
    "frontendIPConfigurations" : [ {
      "name" : "LoadBalancerFrontEnd",
      "properties" : {
        "publicIPAddress" : {
          "id" : "[resourceId('Microsoft.Network/publicIPAddresses', 'myPublicIP')]"
        }
      }
    } ],
    "backendAddressPools" : [ {
      "name" : "BackendPool",
      "properties" : {
        "loadBalancerBackendAddresses" : [ {
          "name" : "api-handler"
        } ]
      }
    } ]
  }
}
{
  "name" : "web-alb",
  "type" : "compute.v1.forwardingRule",
  "properties" : {
    "region" : "us-central1",
    "loadBalancingScheme" : "EXTERNAL",
    "portRange" : "80",
    "target" : "global/targetHttpProxies/my-target-proxy",
    "backendServices" : {
      "backends" : [ {
        "group" : "zones/us-central1-a/instanceGroups/api-handler"
      } ]
    }
  }
}

Configuration Options

Target Configuration

Load balancers can target multiple resources:

val function1 = serverlessFunction("api-v1").withRuntime("nodejs18.x").withHandler("v1.handler").build
val function2 = serverlessFunction("api-v2").withRuntime("nodejs18.x").withHandler("v2.handler").build

val alb = applicationLoadBalancer("api-gateway")
  .withTargets(function1, function2)  // Multiple targets

Use Cases