[Yandex Cloud documentation](../../../index.md) > [Yandex Smart Web Security](../../index.md) > [Tutorials](../index.md) > [Creating an L7 load balancer with a security profile](index.md) > Terraform

# Creating an L7 load balancer in Application Load Balancer with a Smart Web Security profile through Terraform

To create an [L7 load balancer with a Smart Web Security](index.md) profile through Terraform:

1. [Get your cloud ready](#before-begin).
1. [Create your infrastructure](#deploy).
1. [Test the security profile](#test).

If you no longer need the resources you created, [delete them](#clear-out).

## Get your cloud ready {#before-you-begin}

Sign up for Yandex Cloud and create a [billing account](../../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../../billing/quickstart/index.md) and [link](../../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../../resource-manager/concepts/resources-hierarchy.md).

### Required paid resources {#paid-resources}

The infrastructure support costs for an L7 load balancer with a Smart Web Security profile include:
* Fee for continuously running [VMs](../../../compute/concepts/vm.md) (see [Yandex Compute Cloud pricing](../../../compute/pricing.md)).
* Fee for using the [L7 load balancer's](../../../application-load-balancer/concepts/index.md) computing resources (see [Application Load Balancer pricing](../../../application-load-balancer/pricing.md)).
* Fee for requests processed by [security profile](../../concepts/profiles.md) rules (see [Yandex Smart Web Security pricing](../../pricing.md)).

## Create an infrastructure {#deploy}

With [Terraform](https://www.terraform.io/), you can quickly create a cloud infrastructure in Yandex Cloud and manage it using configuration files. These files store the infrastructure description written in HashiCorp Configuration Language (HCL). If you change the configuration files, Terraform automatically detects which part of your configuration is already deployed, and what should be added or removed.

Terraform is distributed under the [Business Source License](https://github.com/hashicorp/terraform/blob/main/LICENSE). The [Yandex Cloud provider for Terraform](https://github.com/yandex-cloud/terraform-provider-yandex) is distributed under the [MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/) license.

For more information about the provider resources, see the guides on the [Terraform](https://www.terraform.io/docs/providers/yandex/index.html) website or [its mirror](../../../terraform/index.md).

To create your infrastructure via Terraform:
1. [Install Terraform](../../../tutorials/infrastructure-management/terraform-quickstart.md#install-terraform), [get authentication credentials](../../../tutorials/infrastructure-management/terraform-quickstart.md#get-credentials), and specify the source for installing the Yandex Cloud provider. For details, see [Configure your provider](../../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider), step 1.
1. Prepare your infrastructure description files:

   {% list tabs group=infrastructure_description %}

   - Ready-made configuration {#ready}

     1. Clone the repository with configuration files.

        ```bash
        git clone https://github.com/yandex-cloud-examples/yc-alb-with-sws-profile.git
        ```

     1. Navigate to the repository directory. It should now contain the following files:
        * `alb-smartwebsecurity-config.tf`: New infrastructure configuration.
        * `alb-smartwebsecurity.auto.tfvars`: User data file.

   - Manually {#manual}

     1. Create a folder for configuration files.
     1. In the folder, create:
        1. `alb-smartwebsecurity-config.tf` configuration file:

           {% cut "alb-smartwebsecurity-config.tf" %}

           ```hcl
           # Declaring variables with sensitive data
           
           variable "folder_id" {
             type = string
           }
           
           variable "vm_user" {
             type = string
           }
           
           variable "ssh_key_path" {
             type = string
           }
           
           variable "allowed_ip" {
             type = string
           }
           
           # Adding other variables
           
           locals {
             zone               = "ru-central1-a"
             network_name       = "web-network"
             subnet_name        = "subnet1"
             sg_vm_name         = "sg-web"
             vm_name            = "test-vm1"
             vm_image_family    = "lemp"
           }
           
           # Configuring the provider
           
           terraform {
             required_providers {
               yandex = {
                 source  = "yandex-cloud/yandex"
                 version = ">= 0.47.0"
               }
             }
           }
           
           provider "yandex" {
             folder_id = var.folder_id
           }
           
           # Creating a cloud network
           
           resource "yandex_vpc_network" "network-1" {
             name = local.network_name
           }
           
           # Creating a subnet
           
           resource "yandex_vpc_subnet" "subnet-1" {
             name           = local.subnet_name
             v4_cidr_blocks = ["192.168.1.0/24"]
             zone           = local.zone
             network_id     = yandex_vpc_network.network-1.id
           }
           
           # Creating a security group
           
           resource "yandex_vpc_security_group" "sg-1" {
             name        = local.sg_vm_name
             network_id  = yandex_vpc_network.network-1.id
             egress {
               protocol       = "ANY"
               description    = "any"
               v4_cidr_blocks = ["0.0.0.0/0"]
               from_port      = 1
               to_port        = 65535
             }
             ingress {
               protocol       = "TCP"
               description    = "ext-http"
               v4_cidr_blocks = ["0.0.0.0/0"]
               port           = 80
             }
             ingress {
               protocol       = "TCP"
               description    = "ext-https"
               v4_cidr_blocks = ["0.0.0.0/0"]
               port           = 443
             }
             ingress {
               protocol          = "TCP"
               description       = "healthchecks"
               predefined_target = "loadbalancer_healthchecks"
               port              = 30080
             }
           }
           
           # Adding a prebuilt VM image
           
           resource "yandex_compute_image" "lamp-vm-image" {
             source_family = local.vm_image_family
           }
           
           resource "yandex_compute_disk" "boot-disk" {
             name     = "bootvmdisk"
             type     = "network-hdd"
             zone     = local.zone
             size     = "20"
             image_id = yandex_compute_image.lamp-vm-image.id
           }
           
           # Creating a VM instance
           
           resource "yandex_compute_instance" "vm" {
             name        = local.vm_name
             platform_id = "standard-v3"
             zone        = local.zone
             resources {
               core_fraction = 20
               cores         = 2
               memory        = 1
             }
             boot_disk {
               disk_id = yandex_compute_disk.boot-disk.id
             }
             network_interface {
               subnet_id          = yandex_vpc_subnet.subnet-1.id
               nat                = true
               security_group_ids = [yandex_vpc_security_group.sg-1.id]
             }
             metadata = {
               user-data = "#cloud-config\nusers:\n  - name: ${var.vm_user}\n    groups: sudo\n    shell: /bin/bash\n    sudo: 'ALL=(ALL) NOPASSWD:ALL'\n    ssh_authorized_keys:\n      - ${file("${var.ssh_key_path}")}"
             }
           }
           
           # Creating a security profile
           
           resource "yandex_sws_security_profile" "demo-profile-simple" {
             name           = "test-profile"
             default_action = "DENY"
             
             # Smart Protection rule providing full protection
             security_rule {
               name     = "smart-protection"
               priority = 999900
           
               smart_protection {
                 mode = "FULL"
               }
             }
           
             # Basic rule, allows traffic from the specified IP address without checking by the Smart Protection rule
             security_rule {
               name     = "my-rule"
               priority = 999800
           
               rule_condition {
                 action = "ALLOW"
                 condition {
                   source_ip {
                     ip_ranges_match {
                       ip_ranges = [var.allowed_ip]
           
                     }
                   }
                 }
               }
             }
           }
           
           # Creating a target group
           
           resource "yandex_alb_target_group" "foo" {
             name           = "test-target-group"
           
             target {
               subnet_id    = yandex_vpc_subnet.subnet-1.id
               ip_address   = yandex_compute_instance.vm.network_interface.0.ip_address
             }
           }
           
           # Creating a backend group
           
           resource "yandex_alb_backend_group" "alb-bg" {
             name                     = "test-backend-group"
           
             http_backend {
               name                   = "backend-1"
               port                   = 80
               target_group_ids       = [yandex_alb_target_group.foo.id]
               healthcheck {
                 timeout              = "10s"
                 interval             = "2s"
                 healthcheck_port     = 80
                 http_healthcheck {
                   path               = "/"
                 }
               }
             }
           }
           
           # Creating an HTTP router
           
           resource "yandex_alb_http_router" "alb-router" {
             name   = "test-http-router"
           }
           
           resource "yandex_alb_virtual_host" "alb-host" {
             name           = "test-virtual-host"
             http_router_id = yandex_alb_http_router.alb-router.id
             authority      = ["*"]
             route {
               name = "route-1"
               http_route {
                 http_route_action {
                   backend_group_id = yandex_alb_backend_group.alb-bg.id
                 }
               }
             }
             route_options {
               security_profile_id   = yandex_sws_security_profile.demo-profile-simple.id
             }
           }
           
           
           # Creating an L7 load balancer
           
           resource "yandex_alb_load_balancer" "sws-balancer" {
             name               = "test-load-balancer"
             network_id         = yandex_vpc_network.network-1.id
             security_group_ids = [yandex_vpc_security_group.sg-1.id]
           
             allocation_policy {
               location {
                 zone_id   = local.zone
                 subnet_id = yandex_vpc_subnet.subnet-1.id
               }
             }
           
             listener {
               name = "listener"
               endpoint {
                 address {
                   external_ipv4_address {
                   }
                 }
                 ports = [80]
               }
               http {
                 handler {
                   http_router_id = yandex_alb_http_router.alb-router.id
                 }
               }
             }
           }
           ```

           {% endcut %}

        1. `alb-smartwebsecurity.auto.tfvars` user data file:

           {% cut "alb-smartwebsecurity.auto.tfvars" %}

           ```hcl
           folder_id    = "<folder_ID>"
           vm_user      = "<VM_user_name>"
           ssh_key_path = "<public_SSH_key_path>"
           allowed_ip   = "<allowed_IP_address_of_device>"
           ```
           {% endcut %}

   {% endlist %}

   For more on the properties of resources used in Terraform, see these provider guides:
   * [Network](../../../vpc/concepts/network.md#network): [yandex_vpc_network](../../../terraform/resources/vpc_network.md)
   * [Subnets](../../../vpc/concepts/network.md#subnet): [yandex_vpc_subnet](../../../terraform/resources/vpc_subnet.md)
   * [Security groups](../../../vpc/concepts/security-groups.md): [yandex_vpc_security_group](../../../terraform/resources/vpc_security_group.md)
   * [VM image](../../../compute/concepts/image.md): [yandex_compute_image](../../../terraform/resources/compute_image.md)
   * [Backend group](../../../application-load-balancer/concepts/backend-group.md): [yandex_alb_backend_group](../../../terraform/resources/alb_backend_group.md)
   * [HTTP router](../../../application-load-balancer/concepts/http-router.md): [yandex_alb_http_router](../../../terraform/resources/alb_http_router.md)
   * [Virtual host](../../../application-load-balancer/concepts/http-router.md#virtual-host): [yandex_alb_virtual_host](../../../terraform/resources/alb_virtual_host.md)
   * [L7 load balancer](../../../application-load-balancer/concepts/application-load-balancer.md): [yandex_alb_load_balancer](../../../terraform/resources/alb_load_balancer.md)
   * [Security profile](../../concepts/profiles.md): [yandex_sws_security_profile](../../../terraform/resources/sws_security_profile.md)

1. In the `alb-smartwebsecurity.auto.tfvars` file, set the following user-defined properties:
   * `folder_id`: [Folder ID](../../../resource-manager/operations/folder/get-id.md).
   * `vm_user`: VM user name.
   * `ssh_key_path`: Path to the public SSH key file. For more information, see [Creating an SSH key pair](../../../compute/operations/vm-connect/ssh.md#creating-ssh-keys).
   * `allowed_ip`: Public IP address of the device that will be sending requests to the L7 load balancer.

1. Create the resources:

   1. In the terminal, navigate to the configuration file directory.
   1. Make sure the configuration is correct using this command:
   
      ```bash
      terraform validate
      ```
   
      If the configuration is valid, you will get this message:
   
      ```bash
      Success! The configuration is valid.
      ```
   
   1. Run this command:
   
      ```bash
      terraform plan
      ```
   
      You will see a list of resources and their properties. No changes will be made at this step. Terraform will show any errors in the configuration.
   1. Apply the configuration changes:
   
      ```bash
      terraform apply
      ```
   
   1. Type `yes` and press **Enter** to confirm the changes.

1. [Get the IP address](../../../application-load-balancer/operations/application-load-balancer-get.md) for your L7 load balancer: you will use it later [to test the security profile](#test).

After creating the infrastructure, test the security profile (#test).

## Test the security profile {#test}

1. Open the terminal on the device whose IP address you specified in the allow rule.
1. Send a request to the test application backend:

    ```bash
    curl --verbose <public_IP_address_of_L7_load_balancer>
    ```

    This command should list the contents of the directory with your test web server.

1. Repeat the request from a different IP address. As a result, you should see a message about a failure to establish a connection to the server.

{% note info %}

Smart protection rules are usually not tested. Such tests would add the properties of suspicious requests, e.g., IP addresses, to a blacklist.

{% endnote %}

## How to delete the resources you created {#clear-out}

To stop paying for the resources you created:

1. Open the `alb-smartwebsecurity-config.tf` file and delete your infrastructure description from it.
1. Apply the changes:

    1. In the terminal, navigate to the configuration file directory.
    1. Make sure the configuration is correct using this command:
    
       ```bash
       terraform validate
       ```
    
       If the configuration is valid, you will get this message:
    
       ```bash
       Success! The configuration is valid.
       ```
    
    1. Run this command:
    
       ```bash
       terraform plan
       ```
    
       You will see a list of resources and their properties. No changes will be made at this step. Terraform will show any errors in the configuration.
    1. Apply the configuration changes:
    
       ```bash
       terraform apply
       ```
    
    1. Type `yes` and press **Enter** to confirm the changes.

#### Useful links {#see-also}

* [Creating an L7 load balancer in Application Load Balancer with a Smart Web Security profile from the management console](console.md)