Creating an L7 load balancer in Application Load Balancer with a Yandex Smart Web Security profile through Terraform
To create an L7 load balancer with a Smart Web Security profile through Terraform:
If you no longer need the resources you created, delete them.
Get your cloud ready
Sign up for Yandex Cloud and create a billing account:
- Navigate to the management console
and log in to Yandex Cloud or create a new account. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one and link a cloud to it.
If you have an active billing account, you can navigate to the cloud page
Learn more about clouds and folders here.
Required paid resources
The infrastructure support costs for an L7 load balancer with a Smart Web Security profile include:
- Fee for continuously running VMs (see Yandex Compute Cloud pricing).
- Fee for using an L7 load balancer’s computing resources (see Application Load Balancer pricing).
- Fee for requests processed by security profile rules (see Yandex Smart Web Security pricing).
Create your infrastructure
With Terraform
Terraform is distributed under the Business Source License
For more information about the provider resources, see the relevant documentation on the Terraform
To create an infrastructure using Terraform:
-
Install Terraform, get the credentials, and specify the source for installing the Yandex Cloud provider (see Configure a provider, Step 1).
-
Prepare your infrastructure description files:
Ready-made configurationManually-
Clone the repository with configuration files:
git clone https://github.com/yandex-cloud-examples/yc-alb-with-sws-profile.git
-
Navigate to the repository directory. Make sure it contains the following files:
alb-smartwebsecurity-config.tf
: New infrastructure configuration.alb-smartwebsecurity.auto.tfvars
: User data file.
- Create a folder for configuration files.
- In the folder, create:
-
alb-smartwebsecurity-config.tf
configuration file:alb-smartwebsecurity-config.tf
# 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 } } } }
-
alb-smartwebsecurity.auto.tfvars
user data file:alb-smartwebsecurity.auto.tfvars
folder_id = "<folder_ID>" vm_user = "<VM_user_name>" ssh_key_path = "<public_SSH_key_path>" allowed_ip = "<allowed_IP_address_of_device>"
-
Learn more about the properties of Terraform resources in the relevant Terraform guides:
- Network: yandex_vpc_network
- Subnets: yandex_vpc_subnet
- Security groups: yandex_vpc_security_group
- VM image: yandex_compute_image
- Backend group: yandex_alb_backend_group
- HTTP router: yandex_alb_http_router
- Virtual host: yandex_alb_virtual_host
- L7 load balancer: yandex_alb_load_balancer
- Security profile: yandex_sws_security_profile
.
-
-
In the
alb-smartwebsecurity.auto.tfvars
file, set the following user-defined properties:folder_id
: Folder ID.vm_user
: VM user name.ssh_key_path
: Path to the public SSH key file. For more information, see Creating an SSH key pair.allowed_ip
: Public IP address of the device that will be sending requests to the L7 load balancer.
-
Create the resources:
-
In the terminal, go to the directory where you edited the configuration file.
-
Make sure the configuration file is correct using this command:
terraform validate
If the configuration is correct, you will get this message:
Success! The configuration is valid.
-
Run this command:
terraform plan
You will see a detailed list of resources. No changes will be made at this step. If the configuration contains any errors, Terraform will show them.
-
Apply the changes:
terraform apply
-
Type
yes
and press Enter to confirm the changes.
-
-
Get the IP address for your L7 load balancer: you will use it later to test the security profile.
After you create the infrastructure, configure DNS and test the security profile.
Configure DNS
-
Add a resource A record to your domain's public DNS zone, with values specified as follows:
Record name
: Your domain's address, ending with a dot. Example:example.com.
ormy.first.example.com.
.Value
: L7 load balancer IP address. To learn the IP address, follow Getting information about an L7 load balancer.
This record will redirect the requests you get at your domain to the L7 load balancer's IP address.
Note
If your domain is delegated to Yandex Cloud DNS, create a resource record according to this guide. Otherwise, use your domain name registrar's personal account. If you have any questions, refer to the relevant documentation or contact the registrar's support service.
-
In your server settings, block all connections except those for Yandex Cloud IP addresses.
Test the security profile
-
Open the terminal on the device whose IP address you specified in the allow rule.
-
Send a request to the test application backend:
curl --verbose <public_IP_address_of_L7_load_balancer>
This command should list the contents of the directory with your test web server.
-
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
Smart protection rules are usually not tested. Such tests would add the properties of suspicious requests, e.g., IP addresses, to a blacklist.
How to delete the resources you created
To stop paying for the resources you created:
-
Open the
alb-smartwebsecurity-config.tf
file and delete your infrastructure description from it. -
Apply the changes:
-
In the terminal, go to the directory where you edited the configuration file.
-
Make sure the configuration file is correct using this command:
terraform validate
If the configuration is correct, you will get this message:
Success! The configuration is valid.
-
Run this command:
terraform plan
You will see a detailed list of resources. No changes will be made at this step. If the configuration contains any errors, Terraform will show them.
-
Apply the changes:
terraform apply
-
Type
yes
and press Enter to confirm the changes.
-