---
title: "Create a security group and assign it to a cloud server port using Terraform"
sidebar_label: "Create a security group and assign it to a cloud server port"
description: "How to create a security group with a rule and assign it to a cloud server port"
sidebar_position: 1
---

import ConfigureProviders from '@site/i18n/en/docusaurus-plugin-content-docs-terraform/current/_partials/common/configure-providers.mdx'
import ConfigureProvidersConfig from '@site/i18n/en/docusaurus-plugin-content-docs-terraform/current/_partials/common/configure-providers-config.mdx'
import CreatePort from '@site/i18n/en/docusaurus-plugin-content-docs-terraform/current/_partials/cloud-servers/create-port.mdx'
import CreateResourcesAlert from '@site/i18n/en/docusaurus-plugin-content-docs-terraform/current/_partials/common/create-resources-alert.mdx'
import CreateBootVolume from '@site/i18n/en/docusaurus-plugin-content-docs-terraform/current/_partials/cloud-servers/create-boot-volume.mdx'
import AddPublicSsh from '@site/i18n/en/docusaurus-plugin-content-docs-terraform/current/_partials/cloud-servers/add-public-ssh-key.mdx'
import CreateFixedServerBootNetwork from '@site/i18n/en/docusaurus-plugin-content-docs-terraform/current/_partials/cloud-servers/create-fixed-server-with-boot-network-volume.mdx'
import GetImage from '@site/i18n/en/docusaurus-plugin-content-docs-terraform/current/_partials/cloud-servers/get-image.mdx'
import CopyIcon from '@selectel/docux/icons/copy'
import Formbricks from '@theme/MDXComponents/Formbricks'

# Create a security group and assign it to a cloud server port using Terraform

<CreateResourcesAlert />

<br />

1. Optional: [configure providers](#configure-providers).
2. [Create a private network and a subnet](#create-networks).
3. [Create a security group](#create-security-group).
4. [Create a rule](#create-rule).
5. [Create a port in the network](#create-port).
6. [Assign the group to a port](#assign-security-group).
7. [Create a server](#create-server).

## Configuration files \{#config}

<details>
  <summary>Example file for configuring providers</summary>

  <ConfigureProvidersConfig />
</details>

<details>
  <summary>Example file for creating a security group and assigning it to a server port</summary>

  ```hcl
  resource "openstack_networking_network_v2" "network_1" {
  name                  = "network"
  port_security_enabled = "true"
  }

  resource "openstack_networking_subnet_v2" "subnet_1" {
    name            = "subnet"
    network_id      = openstack_networking_network_v2.network_1.id
    cidr            = "192.168.0.0/24"
  }

  resource "openstack_networking_secgroup_v2" "security_group_1" {
    name        = "sg"
    description = "Test security group"
  }

  resource "openstack_networking_secgroup_rule_v2" "security_group_rule_1" {
    direction         = "ingress"
    ethertype         = "IPv4"
    protocol          = "tcp"
    port_range_min    = 443
    port_range_max    = 443
    remote_ip_prefix  = "0.0.0.0/0"
    security_group_id = openstack_networking_secgroup_v2.security_group_1.id
  }

  resource "openstack_networking_port_v2" "port_1" {
    name           = "port"
    network_id     = openstack_networking_network_v2.network_1.id
    admin_state_up = "true"

    fixed_ip {
      subnet_id  = openstack_networking_subnet_v2.subnet_1.id
    }
  }

  resource "openstack_networking_port_secgroup_associate_v2" "security_group_associate_1" {
    port_id            = openstack_networking_port_v2.port_1.id
    security_group_ids = [openstack_networking_secgroup_v2.security_group_1.id]
  }

  data "openstack_images_image_v2" "image_1" {
    name        = "Ubuntu 20.04 LTS 64-bit"
    most_recent = true
    visibility  = "public"
  }

  resource "selectel_vpc_keypair_v2" "keypair_1" {
    name       = "keypair"
    public_key = file("~/.ssh/id_rsa.pub")
    user_id    = selectel_iam_serviceuser_v1.serviceuser_1.id
  }

  resource "openstack_blockstorage_volume_v3" "volume_1" {
    name                 = "boot-volume"
    size                 = "5"
    image_id             = data.openstack_images_image_v2.image_1.id
    volume_type          = "fast.ru-9a"
    availability_zone    = "ru-9a"
    enable_online_resize = true

    lifecycle {
      ignore_changes = [image_id]
    }

  }

  resource "openstack_compute_instance_v2" "server_1" {
    name              = "server"
    flavor_id         = "4011"
    key_pair          = selectel_vpc_keypair_v2.keypair_1.name
    availability_zone = "ru-9a"

    network {
      port = openstack_networking_port_v2.port_1.id
    }

    lifecycle {
      ignore_changes = [image_id]
    }

    block_device {
      uuid             = openstack_blockstorage_volume_v3.volume_1.id
      source_type      = "volume"
      destination_type = "volume"
      boot_index       = 0
    }

    vendor_options {
      ignore_resize_confirmation = true
    }
  }

  ```
</details>

## 1. Optional: configure providers \{#configure-providers}

If you [have configured the Selectel and OpenStack providers](/terraform/configure-terraform-environment/#configure-providers), skip this step.

<ConfigureProviders />

## 2. Create a private network and a subnet \{#create-networks}

```hcl
resource "openstack_networking_network_v2" "network_1" {
name                  = "network"
port_security_enabled = "true"
}

resource "openstack_networking_subnet_v2" "subnet_1" {
  name            = "subnet"
  network_id      = openstack_networking_network_v2.network_1.id
  cidr            = "192.168.0.0/24"
}
```

## 3. Create a security group \{#create-security-group}

```hcl
resource "openstack_networking_secgroup_v2" "security_group_1" {
  name        = "sg"
  description = "Test security group"
}
```

See the detailed resource description for [openstack\_networking\_secgroup\_v2](/terraform/openstack-provider-reference/networking-neutron/resources/openstack_networking_secgroup_v2/).

## 4. Create a rule \{#create-rule}

```hcl
resource "openstack_networking_secgroup_rule_v2" "security_group_rule_1" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 443
  port_range_max    = 443
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = openstack_networking_secgroup_v2.security_group_1.id
}
```

Where:

* `direction` — traffic direction: `ingress` for incoming traffic, `egress` for outgoing;
* `ethertype` — protocol type: `IPv4` or `IPv6`;
* `protocol` — protocol, for example `tcp`;
* `port_range_min` — the first port in the range of ports allowed for connection, for example `443`;
* `port_range_max` — the last port in the range;
* `remote_ip_prefix` — IP addresses from which traffic is allowed, for example `0.0.0.0/0`.

See the detailed resource description for [openstack\_networking\_secgroup\_rule\_v2](/terraform/openstack-provider-reference/networking-neutron/resources/openstack_networking_secgroup_rule_v2/).

## 5. Create a port in the network \{#create-port}

<CreatePort />

## 6. Assign the group to a port \{#assign-security-group}

```hcl
resource "openstack_networking_port_secgroup_associate_v2" "security_group_associate_1" {
    port_id            = openstack_networking_port_v2.port_1.id
    security_group_ids = [openstack_networking_secgroup_v2.security_group_1.id]
  }
```

See the detailed resource description for [openstack\_networking\_secgroup\_associate\_v2](/terraform/openstack-provider-reference/networking-neutron/resources/openstack_networking_port_secgroup_associate_v2/).

## 7. Create a cloud server \{#create-server}

### 1. Add a public SSH key \{#add-public-ssh-key}

<AddPublicSsh />

### 2. Get an image⁠ \{#get-image}

<GetImage />

### 3. Create a bootable network volume \{#create-boot-volume}

<CreateBootVolume />

### 4. Create a cloud server \{#create-server}

<CreateFixedServerBootNetwork />

<Formbricks />
