FlexibleEngineCloud / terraform-provider-flexibleengine

Terraform flexibleengine provider
https://www.terraform.io/docs/providers/flexibleengine/
Mozilla Public License 2.0
30 stars 53 forks source link

[ECS/VPC] feature request: add support for Disabling Source and Destination Check #371

Closed gberche-orange closed 4 years ago

gberche-orange commented 4 years ago

Note: I'm not sure how this option is currently supported in the huawei cloud api. I have not yet found it into the following api endpoints including Virtual Private Cloud > API Reference> OpenStack Neutron APIs> Port> Creating a Port

Surprisingly, the flexible engine UI translates the "disable check" button into the following rest call https://console.prod-cloud-ocb.orange-business.com/ecm/rest/v1/491849b50fb94252893dc396ecfdb600/cloudservers/nics/b3e8c2ce-0084-4c6a-81f9-292083da24ea with body

    {"nic":{"subnet_id":"","ip_address":"1.1.1.1/0"}}

While the "enable check" button translates https://console.prod-cloud-ocb.orange-business.com/ecm/rest/v1/491849b50fb94252893dc396ecfdb600/cloudservers/nics/b3e8c2ce-0084-4c6a-81f9-292083da24ea with body

    {}

This looks like if the UI is using a specific magic ip address format to control this flag. Is this something that is currently possible using the terraform provider as well, such as with https://www.terraform.io/docs/providers/flexibleengine/r/compute_interface_attach_v2.html ?

/CC @poblin-orange

gberche-orange commented 4 years ago

The openstack API at https://support.huaweicloud.com/intl/en-us/api-vpc/vpc_port01_0006.html#vpc_port01_0006__table2033432574917 seems to imply the ip address in the allowed_adresss_pair can accept a CIDR and hence a 1.1.1.1/0 block

image

whereas the terraform provider does not (yet?) describe this CIDR support at https://www.terraform.io/docs/providers/flexibleengine/r/networking_port_v2.html#allowed_address_pairs

image

DafuSHI commented 4 years ago

@niuzhenguo Please help on this subject. An important internal project is blocked by the source ip check feature from Terraform

niuzhenguo commented 4 years ago

@ShiChangkuo Please help with this.

ShiChangkuo commented 4 years ago

@gberche-orange Sorry for late reply, have you tried the allowed_address_pairs block in flexibleengine_networking_port_v2 resource or could you provide the terraform script?

gberche-orange commented 4 years ago

thanks @ShiChangkuo for your response. We have worked around for now the issue with a manual check in the UI, but plan to test usage of the flexibleengine_networking_port_v2 resource with a CIDR (when our priorities would allow it).

In the meantime, would it be possible to improve the documentation of terraform-provider-flexibleengine to make the support of CIDR explici (for instance by providing examples with both single address and cidrs)

ShiChangkuo commented 4 years ago

sure, I will test it then update the documentation.

ShiChangkuo commented 4 years ago

@gberche-orange I have updated the documentation. The value of allowed_address_pairs/id_address can be an IP address or a CIDR. Please let me know how the allowed_address_pairs block worked for you. I am looking forward to your feedback.

gberche-orange commented 4 years ago

thanks @ShiChangkuo for the documentation update!

We'll test and reopen an issue if we have problems using the CIDR syntax.

Arkhenys commented 1 year ago

Hello everyone,

As already discussed with @gberche-orange we faced the same issue in my team. Thanks to Guillaume, his colleagues and few days of work, we were able to solve the issue and have the possibility to disable the source/destination check directly in the terraform plan.

We had to first, declare a flexibleengine_networking_port_v2 before the instance declaration. Then we added the allowed_address_pairs block in the flexibleengine_networking_port_v2 declaration. Finally we had to link the port to the instance using the network block.

Here is what we did in details:

  1. Retrieve secgroup ids : We will see it in a next point, but this will allow us to set the secgroups directly in the flexibleengine_networking_port_v2, not in the instance. To declare secgroups in the port, we have to use a set of IDs, instead of using a set of secgroup names in the instance declaration. We use a for_each = toset() because our current plans send a set of secgroup names when creating an ECS.
# Build a datasource for each security group
data "flexibleengine_networking_secgroup_v2" "secgroup" {
 for_each = toset(var.security_groups)
 name     = each.key
}
  1. Build a set in the locals. Set is mandatory as the created flexibleengine_networking_port_v2 waits for a set of security group ids in its parameters.
locals {
 sec_groups_ids = [for secgroup indata.flexibleengine_networking_secgroup_v2.secgroup: secgroup.id]
}
  1. Create the flexibleengine_networking_port_v2 that will contain the allowed_address_pairs block. Here is the reason we had to declare secgroups in port and not in instance anymore. Port secgroups have a higher priority than instance secgroups. Because of that, our instances were all linked to the default secgroup and not in the one we expected.
resource "flexibleengine_networking_port_v2" "port" {
  network_id         = data.flexibleengine_vpc_subnet_v1.subnet.id
  security_group_ids = local.sec_groups_ids
  admin_state_up     = "true"

  allowed_address_pairs {
    ip_address       = "1.1.1.1/0"
  }

  fixed_ip {
    subnet_id        = data.flexibleengine_vpc_subnet_v1.subnet.ipv4_subnet_id
    ip_address       = var.ip_v4
  }
}
  1. Finally, all we have to do left is to link the flexibleengine_networking_port_v2 to the instance, in the network block.
resource "flexibleengine_compute_instance_v2" "ecs" {

  name                    = var.name
  flavor_id               = var.flavor_id
  key_pair                = var.key_pair

  block_device {
    uuid                  = var.image_id
    source_type           = "image"
    volume_size           = var.volume_size
    volume_type           = var.volume_type
    boot_index            = 0
    destination_type      = "volume"
    delete_on_termination = true
  }

  network {
    port                  = flexibleengine_networking_port_v2.port.id
  }

  user_data               = var.user_data
  tags                    = var.tags
  metadata                = var.metadata

  depends_on              = [flexibleengine_networking_port_v2.port]

}

After that, if you deploy a new instance, it will have source/destination option unchecked (and your instance will be in the expected secgroup).

Arkhenys commented 1 year ago

In addition to my previous message, I would highly recommand using a boolean to enable/disable this option. This can easily be done using the dynamic block expression of terraform.

If you use a module for example, you could declare the boolean variable in your input variables (variables.tf file) such as

variable "source_dest_check_enabled" {
  type        = bool
  default     = true
}

In my example I set it to true because I want the option enabled by default and disabled on demand.

You can then choose to activate or not the option by changing the content of the allowed_address_pairs block in the flexibleengine_networking_port_v2 on a condition. This is where the dynamic block do the trick :

resource "flexibleengine_networking_port_v2" "port" {
  network_id         = data.flexibleengine_vpc_subnet_v1.subnet.id
  security_group_ids = local.sec_groups_ids
  admin_state_up     = "true"

  dynamic "allowed_address_pairs" {
    for_each         = var.source_dest_check_enabled ? [] : [1]

    content {
      ip_address     = "1.1.1.1/0"
    }
  }

  fixed_ip {
    subnet_id        = data.flexibleengine_vpc_subnet_v1.subnet.ipv4_subnet_id
    ip_address       = var.ip_v4
  }
}

Here is the explaination of this block :