Service Blocks

Service blocks contain the majority of the Cloudscript code, including the default provider, infrastructure, configuration, containers and deployment specifications.

service "webapp" {
  provider = "aws"
  
  infrastructure {
    network "vpc" {
      cidr_block           = "10.0.0.0/16"
      enable_dns_hostnames = true
      enable_dns_support   = true
      tags = {
        Name = "main-vpc"
      }
      resource_type = "aws_vpc"
    }

    network "subnet1" {
      vpc_id            = "${infrastructure.network.vpc.id}"
      cidr_block        = "10.0.1.0/24"
      availability_zone = "us-east-1a"
      resource_type     = "aws_subnet"
    }

    network "subnet2" {
      vpc_id            = "${infrastructure.network.vpc.id}"
      cidr_block        = "10.0.2.0/24"
      availability_zone = "us-east-1b"
      resource_type     = "aws_subnet"
    }

    network "internet_gateway" {
      vpc_id        = "${infrastructure.network.vpc.id}"
      tags = {
        Name = "main"
      }
      resource_type = "aws_internet_gateway"
    }

    network "route_table" {
      vpc_id = "${infrastructure.network.vpc.id}"
      route = [
        {
          cidr_block = "0.0.0.0/0"
          gateway_id = "${infrastructure.network.internet_gateway.id}"
        }
      ]
      resource_type = "aws_route_table"
    }

    network "route_table_association_subnet1" {
      subnet_id      = "${infrastructure.network.subnet1.id}"
      route_table_id = "${infrastructure.network.route_table.id}"
      resource_type  = "aws_route_table_association"
    }

    network "route_table_association_subnet2" {
      subnet_id      = "${infrastructure.network.subnet2.id}"
      route_table_id = "${infrastructure.network.route_table.id}"
      resource_type  = "aws_route_table_association"
    }

    iam "eks_cluster" {
      name               = "eks_cluster"
      assume_role_policy = file("role.json")
      resource_type      = "aws_iam_role"
    }

    iam "eks_cluster_policy_attachment" {
      role        = "${infrastructure.iam.eks_cluster.name}"
      policy_arn  = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
      resource_type = "aws_iam_role_policy_attachment"
    }

    compute "eks_cluster" {
      name       = "main"
      role_arn   = "${infrastructure.iam.eks_cluster.arn}"
      vpc_config = {
        subnet_ids = [
          "${infrastructure.network.subnet1.id}",
          "${infrastructure.network.subnet2.id}"
        ]
      }
      depends_on    = ["infrastructure.iam.eks_cluster_policy_attachment"]
      resource_type  = "aws_eks_cluster"
    }

    compute "web_server" {
      instance_type         = "t2.micro"
      ami                   = "ami-005fc0f236362e99f"
      subnet_id             = "${infrastructure.network.subnet1.id}"
      tags = {
        Name = "main_web_server"
      }
      key_name              = "cloud-cli-key"
      depends_on            = ["infrastructure.network.vpc"]
      resource_type         = "aws_instance"
    }
  }

  configuration {
    play "webapp" {
      name   = "Configure webapp"
      hosts  = "{{ target_servers | default('all') }}"
      become = true
      vars = {
        target_web_servers = "web_servers"
        target_db_servers  = "db_servers"
      }

      task {
        name = "Packages tasks"
        block {
          task {
            name          = "Install required packages"
            package {
              name          = "{{ item }}"
              state         = "present"
              update_cache  = true
            }
            loop = ["nginx", "docker"]
          }
        }
      }

      task {
        name = "Other tasks"
        block {
          task {
            name     = "Create/modify /etc/nginx/nginx.conf"
            copy {
              dest    = "/etc/nginx/nginx.conf"
              content = file("nginx.conf")
              mode    = "0644"
              owner   = "root"
              group   = "root"
            }
            notify = ["restart nginx"]
            when   = "ansible_distribution == 'Ubuntu'"
          }

          task {
            name            = "Ensure nginx is started"
            service {
              name    = "nginx"
              state   = "started"
              enabled = "yes"
            }
            register          = "nginx_started_result"
            retries           = 3
            delay             = 5
            failed_when       = "nginx_started_result is failed"
            changed_when      = "nginx_started_result is changed"
            when              = "ansible_distribution == 'Ubuntu'"
          }

          task {
            name            = "Verify nginx"
            command         = "systemctl is-active nginx"
            register        = "verify_nginx"
            failed_when     = "verify_nginx.rc != 0"
            changed_when    = false
            retries         = 1
            delay           = 5
          }
        }
      }

      handler {
        name    = "restart nginx"
        service {
          name  = "nginx"
          state = "restarted"
        }
      }
    }
  }

  containers {
    app "web_app" {
      image             = "nginx:latest"
      type              = "Deployment"
      replicas          = 3
      command           = ["/bin/sh"]
      args              = ["-c", "nginx -g 'daemon off;'"]
      working_dir       = "/usr/share/nginx/html"

      readiness_probe = {
        http_get = {
          path = "/healthz"
          port = 80
        }
        initial_delay_seconds = 5
        period_seconds        = 10
      }

      resources = {
        limits = {
          cpu    = "500m"
          memory = "512Mi"
        }
        requests = {
          cpu    = "250m"
          memory = "256Mi"
        }
      }

      empty_dir_volumes = [
        {
          name       = "cache"
          size_limit = "1Gi"
        }
      ]

      volume_mounts = [
        {
          name      = "cache"
          mountPath = "/cache"
        }
      ]

      ports = [
        {
          container_port = 80
          service_port   = 80
        }
      ]

      service = {
        type        = "LoadBalancer"
        annotations = {
          "service.beta.kubernetes.io/aws-load-balancer-type" = "nlb"
        }
      }

      node_selector = {
        "kubernetes.io/os" = "linux"
        "node-type"        = "web"
      }

      auto_scaling = {
        min_replicas                      = 2
        max_replicas                      = 10
        target_cpu_utilization_percentage = 80
      }
    }
  }

  deployment {
    "infrastructure.compute.web_server" maps_to "configuration.play.webapp"
  }
}

Last updated