{"id":34741809,"url":"https://github.com/tf-scaleway-modules/terraform-scaleway-compute","last_synced_at":"2026-04-27T13:00:29.224Z","repository":{"id":330374424,"uuid":"1119472307","full_name":"tf-scaleway-modules/terraform-scaleway-compute","owner":"tf-scaleway-modules","description":"A Terraform module for creating and managing Scaleway Compute infrastructure","archived":false,"fork":false,"pushed_at":"2025-12-25T02:05:44.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-26T15:20:03.987Z","etag":null,"topics":["compute","modules","scaleway","terraform"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tf-scaleway-modules.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-19T10:21:51.000Z","updated_at":"2025-12-25T02:05:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tf-scaleway-modules/terraform-scaleway-compute","commit_stats":null,"previous_names":["tf-scaleway-modules/terraform-scaleway-compute"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/tf-scaleway-modules/terraform-scaleway-compute","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tf-scaleway-modules%2Fterraform-scaleway-compute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tf-scaleway-modules%2Fterraform-scaleway-compute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tf-scaleway-modules%2Fterraform-scaleway-compute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tf-scaleway-modules%2Fterraform-scaleway-compute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tf-scaleway-modules","download_url":"https://codeload.github.com/tf-scaleway-modules/terraform-scaleway-compute/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tf-scaleway-modules%2Fterraform-scaleway-compute/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32337274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compute","modules","scaleway","terraform"],"created_at":"2025-12-25T04:16:29.514Z","updated_at":"2026-04-27T13:00:29.213Z","avatar_url":"https://github.com/tf-scaleway-modules.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Scaleway Compute Terraform Module\n\n[![Apache 2.0][apache-shield]][apache]\n[![Terraform][terraform-badge]][terraform-url]\n[![Scaleway Provider][scaleway-badge]][scaleway-url]\n[![Latest Release][release-badge]][release-url]\n\nA production-ready Terraform module for creating and managing **Scaleway** Compute infrastructure.\n\n## Features\n\n- **Multi-Instance Groups**: Define multiple groups (backend, frontend, database) with different configurations\n- **Two-Tier Security Groups**: Shared security group for all instances + per-group security groups with merged rules\n- **Multiple Private Networks**: Connect instances to multiple VPC private networks simultaneously\n- **SBS Block Storage**: Additional SBS volumes per instance with configurable IOPS (5k/15k)\n- **External Volume Attachment**: Attach externally created volumes to instances via IDs\n- **Placement Groups**: High availability or low latency configurations\n- **Cloud-Init**: Full cloud-init and user data support per group\n- **SSH Keys**: Automatic SSH key management\n- **Backup Snapshots**: Optional snapshot creation per instance group\n- **Reserved IPs**: Static public IP allocation per instance\n\n## Usage Examples\n\nComprehensive examples are available in the [`examples/`](examples/) directory:\n\n- **[Minimal](examples/minimal/)** - Simplest configuration for quick start\n- **[Complete](examples/complete/)** - Full-featured production setup\n\n### Quick Start\n\n```hcl\nmodule \"compute\" {\n  source = \"git::https://gitlab.com/leminnov/terraform/modules/scaleway-compute.git\"\n\n  organization_id = \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n  project_name    = \"myproject\"\n  name            = \"myapp\"  # Used for resource naming: myapp-web-00, myapp-shared-sg, etc.\n\n  instances = {\n    web = {\n      count         = 1\n      instance_type = \"DEV1-S\"\n    }\n  }\n\n  # Global inbound rules (apply to shared security group)\n  inbound_rules = [\n    { protocol = \"TCP\", port = 22 }\n  ]\n}\n```\n\n### Production Setup with Multiple Instance Groups\n\n```hcl\n# Create VPC private networks\nresource \"scaleway_vpc_private_network\" \"main\" {\n  name = \"main-network\"\n}\n\nresource \"scaleway_vpc_private_network\" \"data\" {\n  name = \"data-network\"\n}\n\nmodule \"compute\" {\n  source = \"git::https://gitlab.com/leminnov/terraform/modules/scaleway-compute.git\"\n\n  organization_id = \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n  project_name    = \"ecommerce\"\n  name            = \"ecommerce-prod\"\n  zone            = \"fr-par-1\"\n\n  tags = [\"production\"]\n\n  # Default private network for all instances\n  private_networks = [\n    { id = scaleway_vpc_private_network.main.id },\n  ]\n\n  # Multiple instance groups with different configurations\n  instances = {\n    backend = {\n      count               = 3\n      instance_type       = \"GP1-S\"\n      image               = \"ubuntu_noble\"\n      root_volume_size_gb = 50\n      tags                = [\"backend\", \"api\"]\n\n      cloud_init = \u003c\u003c-EOF\n        #cloud-config\n        packages: [docker.io]\n      EOF\n    }\n\n    frontend = {\n      count               = 2\n      instance_type       = \"DEV1-M\"\n      image               = \"ubuntu_noble\"\n      root_volume_size_gb = 30\n      tags                = [\"frontend\", \"web\"]\n    }\n\n    database = {\n      count                  = 1\n      instance_type          = \"GP1-M\"\n      enable_backup_snapshot = true\n      create_public_ip       = false\n\n      # SBS volumes with configurable IOPS\n      additional_volumes = [\n        { size_gb = 200, type = \"sbs_5k\" },   # 5000 IOPS\n        { size_gb = 100, type = \"sbs_15k\" },  # 15000 IOPS\n      ]\n\n      # Database connects to both networks\n      private_networks = [\n        { id = scaleway_vpc_private_network.main.id },\n        { id = scaleway_vpc_private_network.data.id },\n      ]\n\n      # Per-group security rules (MERGED with global rules)\n      # This group gets: SSH (global) + PostgreSQL (group-specific)\n      inbound_rules = [\n        { protocol = \"TCP\", port = 5432, ip_range = \"10.0.0.0/8\" },\n      ]\n    }\n  }\n\n  # HA placement\n  create_placement_group      = true\n  placement_group_policy_type = \"max_availability\"\n\n  # Global security rules (apply to shared SG + merged into per-group SGs)\n  inbound_rules = [\n    { protocol = \"TCP\", port = 22, ip_range = \"10.0.0.0/8\" },\n    { protocol = \"TCP\", port = 443 },\n  ]\n}\n```\n\n## Security Group Architecture\n\nThis module uses a **two-tier security group architecture**:\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                    Security Group Architecture                   │\n├─────────────────────────────────────────────────────────────────┤\n│                                                                  │\n│  ┌──────────────────────────────────────────────────────────┐   │\n│  │           SHARED SECURITY GROUP (name-shared-sg)          │   │\n│  │                                                            │   │\n│  │  Contains: Global inbound_rules + outbound_rules           │   │\n│  │  Applied to: All instances WITHOUT custom rules            │   │\n│  │                                                            │   │\n│  │  Examples: backend, frontend groups                        │   │\n│  └──────────────────────────────────────────────────────────┘   │\n│                                                                  │\n│  ┌──────────────────────────────────────────────────────────┐   │\n│  │        PER-GROUP SECURITY GROUPS (name-{group}-sg)        │   │\n│  │                                                            │   │\n│  │  Contains: Global rules + Group-specific rules (MERGED)    │   │\n│  │  Created when: Group specifies custom inbound/outbound     │   │\n│  │                                                            │   │\n│  │  Example: database group with PostgreSQL rules             │   │\n│  └──────────────────────────────────────────────────────────┘   │\n│                                                                  │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### How it works\n\n| Instance Group | Has Custom Rules? | Security Group Used | Rules Applied |\n|---------------|-------------------|---------------------|---------------|\n| `backend` | No | `name-shared-sg` | Global rules only |\n| `frontend` | No | `name-shared-sg` | Global rules only |\n| `database` | Yes | `name-database-sg` | Global + PostgreSQL rules |\n| `cache` | Yes | `name-cache-sg` | Global + Redis rules |\n\n### Outputs\n\n```hcl\n# Get the shared security group ID\nmodule.compute.shared_security_group_id\n\n# Get per-group security group IDs (only groups with custom rules)\nmodule.compute.group_security_group_ids[\"database\"]\nmodule.compute.group_security_group_ids[\"cache\"]\n\n# Get all security groups with details\nmodule.compute.security_groups\n```\n\n\u003c!-- BEGIN_TF_DOCS --\u003e\n## Requirements\n\n| Name | Version |\n| ---- | ------- |\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 1.10.7 |\n| \u003ca name=\"requirement_scaleway\"\u003e\u003c/a\u003e [scaleway](#requirement\\_scaleway) | ~\u003e 2.73 |\n\n## Providers\n\n| Name | Version |\n| ---- | ------- |\n| \u003ca name=\"provider_scaleway\"\u003e\u003c/a\u003e [scaleway](#provider\\_scaleway) | 2.73.0 |\n\n## Modules\n\nNo modules.\n\n## Resources\n\n| Name | Type |\n| ---- | ---- |\n| [scaleway_block_volume.this](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/block_volume) | resource |\n| [scaleway_iam_ssh_key.this](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/iam_ssh_key) | resource |\n| [scaleway_instance_ip.this](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_ip) | resource |\n| [scaleway_instance_placement_group.this](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_placement_group) | resource |\n| [scaleway_instance_security_group.group](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_security_group) | resource |\n| [scaleway_instance_security_group.shared](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_security_group) | resource |\n| [scaleway_instance_security_group_rules.group](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_security_group_rules) | resource |\n| [scaleway_instance_security_group_rules.shared](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_security_group_rules) | resource |\n| [scaleway_instance_server.this](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_server) | resource |\n| [scaleway_instance_snapshot.this](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_snapshot) | resource |\n| [scaleway_instance_volume.this](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/instance_volume) | resource |\n| [scaleway_account_project.project](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/data-sources/account_project) | data source |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n| ---- | ----------- | ---- | ------- | :------: |\n| \u003ca name=\"input_create_placement_group\"\u003e\u003c/a\u003e [create\\_placement\\_group](#input\\_create\\_placement\\_group) | Create a shared placement group. | `bool` | `false` | no |\n| \u003ca name=\"input_create_security_group\"\u003e\u003c/a\u003e [create\\_security\\_group](#input\\_create\\_security\\_group) | Create a shared security group for all instances. | `bool` | `true` | no |\n| \u003ca name=\"input_create_ssh_key\"\u003e\u003c/a\u003e [create\\_ssh\\_key](#input\\_create\\_ssh\\_key) | Create and upload an SSH key. | `bool` | `false` | no |\n| \u003ca name=\"input_inbound_default_policy\"\u003e\u003c/a\u003e [inbound\\_default\\_policy](#input\\_inbound\\_default\\_policy) | Default inbound policy: accept or drop. | `string` | `\"drop\"` | no |\n| \u003ca name=\"input_inbound_rules\"\u003e\u003c/a\u003e [inbound\\_rules](#input\\_inbound\\_rules) | Inbound security group rules. | \u003cpre\u003elist(object({\u003cbr/\u003e    action     = optional(string, \"accept\")\u003cbr/\u003e    protocol   = optional(string, \"TCP\")\u003cbr/\u003e    port       = optional(number)\u003cbr/\u003e    port_range = optional(string)\u003cbr/\u003e    ip_range   = optional(string, \"0.0.0.0/0\")\u003cbr/\u003e  }))\u003c/pre\u003e | \u003cpre\u003e[\u003cbr/\u003e  {\u003cbr/\u003e    \"ip_range\": \"0.0.0.0/0\",\u003cbr/\u003e    \"port\": 22,\u003cbr/\u003e    \"protocol\": \"TCP\"\u003cbr/\u003e  }\u003cbr/\u003e]\u003c/pre\u003e | no |\n| \u003ca name=\"input_instances\"\u003e\u003c/a\u003e [instances](#input\\_instances) | Map of instance groups to create. Each group can have different count, type, image, etc. | \u003cpre\u003emap(object({\u003cbr/\u003e    count               = number\u003cbr/\u003e    instance_type       = string\u003cbr/\u003e    image               = optional(string, \"ubuntu_noble\")\u003cbr/\u003e    root_volume_size_gb = optional(number, 20)\u003cbr/\u003e    root_volume_type    = optional(string, \"l_ssd\")\u003cbr/\u003e    state               = optional(string, \"started\")\u003cbr/\u003e    tags                = optional(list(string), [])\u003cbr/\u003e    cloud_init          = optional(string)\u003cbr/\u003e    user_data           = optional(map(string), {})\u003cbr/\u003e    create_public_ip    = optional(bool, true)\u003cbr/\u003e    private_networks = optional(list(object({\u003cbr/\u003e      id         = string\u003cbr/\u003e      ip_address = optional(string)\u003cbr/\u003e    })), [])\u003cbr/\u003e    security_group_id       = optional(string)\u003cbr/\u003e    create_security_group   = optional(bool)\u003cbr/\u003e    inbound_default_policy  = optional(string)\u003cbr/\u003e    outbound_default_policy = optional(string)\u003cbr/\u003e    stateful                = optional(bool)\u003cbr/\u003e    inbound_rules = optional(list(object({\u003cbr/\u003e      action     = optional(string, \"accept\")\u003cbr/\u003e      protocol   = optional(string, \"TCP\")\u003cbr/\u003e      port       = optional(number)\u003cbr/\u003e      port_range = optional(string)\u003cbr/\u003e      ip_range   = optional(string, \"0.0.0.0/0\")\u003cbr/\u003e    })))\u003cbr/\u003e    outbound_rules = optional(list(object({\u003cbr/\u003e      action     = optional(string, \"accept\")\u003cbr/\u003e      protocol   = optional(string, \"TCP\")\u003cbr/\u003e      port       = optional(number)\u003cbr/\u003e      port_range = optional(string)\u003cbr/\u003e      ip_range   = optional(string, \"0.0.0.0/0\")\u003cbr/\u003e    })))\u003cbr/\u003e    placement_group_id     = optional(string)\u003cbr/\u003e    enable_backup_snapshot = optional(bool, false)\u003cbr/\u003e    additional_volumes = optional(list(object({\u003cbr/\u003e      size_gb = number\u003cbr/\u003e      type    = optional(string, \"sbs_5k\")\u003cbr/\u003e      iops    = optional(number)\u003cbr/\u003e    })), [])\u003cbr/\u003e    # Block volumes can only be attached to ONE instance at a time, so external_volume_ids\u003cbr/\u003e    # is only valid when count \u003c= 1. Enforced by precondition on scaleway_instance_server.this.\u003cbr/\u003e    external_volume_ids = optional(list(string), [])\u003cbr/\u003e  }))\u003c/pre\u003e | n/a | yes |\n| \u003ca name=\"input_name\"\u003e\u003c/a\u003e [name](#input\\_name) | Workload name used as a prefix for resource naming and tagging. | `string` | n/a | yes |\n| \u003ca name=\"input_organization_id\"\u003e\u003c/a\u003e [organization\\_id](#input\\_organization\\_id) | Scaleway Organization ID. | `string` | n/a | yes |\n| \u003ca name=\"input_outbound_default_policy\"\u003e\u003c/a\u003e [outbound\\_default\\_policy](#input\\_outbound\\_default\\_policy) | Default outbound policy: accept or drop. | `string` | `\"accept\"` | no |\n| \u003ca name=\"input_outbound_rules\"\u003e\u003c/a\u003e [outbound\\_rules](#input\\_outbound\\_rules) | Outbound security group rules. | \u003cpre\u003elist(object({\u003cbr/\u003e    action     = optional(string, \"accept\")\u003cbr/\u003e    protocol   = optional(string, \"TCP\")\u003cbr/\u003e    port       = optional(number)\u003cbr/\u003e    port_range = optional(string)\u003cbr/\u003e    ip_range   = optional(string, \"0.0.0.0/0\")\u003cbr/\u003e  }))\u003c/pre\u003e | `[]` | no |\n| \u003ca name=\"input_placement_group_id\"\u003e\u003c/a\u003e [placement\\_group\\_id](#input\\_placement\\_group\\_id) | ID of existing placement group. | `string` | `null` | no |\n| \u003ca name=\"input_placement_group_policy_mode\"\u003e\u003c/a\u003e [placement\\_group\\_policy\\_mode](#input\\_placement\\_group\\_policy\\_mode) | Placement mode: optional or enforced. | `string` | `\"optional\"` | no |\n| \u003ca name=\"input_placement_group_policy_type\"\u003e\u003c/a\u003e [placement\\_group\\_policy\\_type](#input\\_placement\\_group\\_policy\\_type) | Placement policy: low\\_latency or max\\_availability. | `string` | `\"max_availability\"` | no |\n| \u003ca name=\"input_private_networks\"\u003e\u003c/a\u003e [private\\_networks](#input\\_private\\_networks) | Default private networks for all instances. Each network can have an optional static IP. | \u003cpre\u003elist(object({\u003cbr/\u003e    id         = string\u003cbr/\u003e    ip_address = optional(string)\u003cbr/\u003e  }))\u003c/pre\u003e | `[]` | no |\n| \u003ca name=\"input_project_name\"\u003e\u003c/a\u003e [project\\_name](#input\\_project\\_name) | Scaleway Project name where all resources will be created. | `string` | n/a | yes |\n| \u003ca name=\"input_public_ip_type\"\u003e\u003c/a\u003e [public\\_ip\\_type](#input\\_public\\_ip\\_type) | Type of public IP: routed\\_ipv4, routed\\_ipv6, or nat. | `string` | `\"routed_ipv4\"` | no |\n| \u003ca name=\"input_security_group_id\"\u003e\u003c/a\u003e [security\\_group\\_id](#input\\_security\\_group\\_id) | ID of existing security group (when create\\_security\\_group is false). | `string` | `null` | no |\n| \u003ca name=\"input_ssh_public_key\"\u003e\u003c/a\u003e [ssh\\_public\\_key](#input\\_ssh\\_public\\_key) | SSH public key content. | `string` | `null` | no |\n| \u003ca name=\"input_ssh_public_key_file\"\u003e\u003c/a\u003e [ssh\\_public\\_key\\_file](#input\\_ssh\\_public\\_key\\_file) | Path to SSH public key file. | `string` | `null` | no |\n| \u003ca name=\"input_stateful\"\u003e\u003c/a\u003e [stateful](#input\\_stateful) | Enable stateful security group. | `bool` | `true` | no |\n| \u003ca name=\"input_tags\"\u003e\u003c/a\u003e [tags](#input\\_tags) | Global tags applied to all resources. | `list(string)` | `[]` | no |\n| \u003ca name=\"input_timeouts\"\u003e\u003c/a\u003e [timeouts](#input\\_timeouts) | Resource operation timeouts for create, update, and delete operations. | \u003cpre\u003eobject({\u003cbr/\u003e    create = optional(string, \"10m\")\u003cbr/\u003e    update = optional(string, \"10m\")\u003cbr/\u003e    delete = optional(string, \"10m\")\u003cbr/\u003e  })\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_zone\"\u003e\u003c/a\u003e [zone](#input\\_zone) | Scaleway zone (e.g., fr-par-1, nl-ams-1). | `string` | `\"fr-par-1\"` | no |\n\n## Outputs\n\n| Name | Description |\n| ---- | ----------- |\n| \u003ca name=\"output_block_volumes\"\u003e\u003c/a\u003e [block\\_volumes](#output\\_block\\_volumes) | Map of additional SBS block volumes keyed by volume key. |\n| \u003ca name=\"output_group_security_group_ids\"\u003e\u003c/a\u003e [group\\_security\\_group\\_ids](#output\\_group\\_security\\_group\\_ids) | Map of instance group names to their dedicated security group IDs (only groups with custom rules). |\n| \u003ca name=\"output_instances\"\u003e\u003c/a\u003e [instances](#output\\_instances) | Map of all instances keyed by '\u003cgroup\u003e-\u003cindex\u003e' with id, name, type, state, zone, public\\_ip, private\\_ip. |\n| \u003ca name=\"output_instances_by_group\"\u003e\u003c/a\u003e [instances\\_by\\_group](#output\\_instances\\_by\\_group) | Instances grouped by their instance group name. |\n| \u003ca name=\"output_placement_group_id\"\u003e\u003c/a\u003e [placement\\_group\\_id](#output\\_placement\\_group\\_id) | ID of the shared placement group, or var.placement\\_group\\_id when create\\_placement\\_group is false. |\n| \u003ca name=\"output_private_ips\"\u003e\u003c/a\u003e [private\\_ips](#output\\_private\\_ips) | Map of instance keys to private IP addresses. |\n| \u003ca name=\"output_project_id\"\u003e\u003c/a\u003e [project\\_id](#output\\_project\\_id) | Scaleway Project ID resolved from project\\_name via the account data source. |\n| \u003ca name=\"output_public_ips\"\u003e\u003c/a\u003e [public\\_ips](#output\\_public\\_ips) | Map of instance keys to public IP addresses. |\n| \u003ca name=\"output_security_groups\"\u003e\u003c/a\u003e [security\\_groups](#output\\_security\\_groups) | All security groups (shared + per-group) keyed by name with id and full name. |\n| \u003ca name=\"output_shared_security_group_id\"\u003e\u003c/a\u003e [shared\\_security\\_group\\_id](#output\\_shared\\_security\\_group\\_id) | ID of the shared security group, or var.security\\_group\\_id when create\\_security\\_group is false. |\n| \u003ca name=\"output_ssh_key_id\"\u003e\u003c/a\u003e [ssh\\_key\\_id](#output\\_ssh\\_key\\_id) | ID of the SSH key created by the module (null when create\\_ssh\\_key is false). |\n| \u003ca name=\"output_volumes\"\u003e\u003c/a\u003e [volumes](#output\\_volumes) | Map of additional local (l\\_ssd) volumes keyed by volume key. |\n\u003c!-- END_TF_DOCS --\u003e\n\n## Security Considerations\n\n- Default inbound policy is `drop` - only explicitly allowed traffic is permitted\n- SSH access is restricted by default - consider limiting to specific IP ranges\n- Enable `stateful` security groups for automatic return traffic handling\n- Use private networks for inter-instance communication\n- Groups with custom rules get a dedicated security group with merged rules (global + group-specific)\n- Use `security_group_id` at group level to attach an external security group instead of creating one\n\n## Resource Timeouts\n\nConfigure operation timeouts using the `timeouts` variable:\n\n```hcl\nmodule \"compute\" {\n  source = \"...\"\n\n  timeouts = {\n    create = \"20m\"  # Instance creation (default: 10m)\n    update = \"15m\"  # Instance updates (default: 10m)\n    delete = \"10m\"  # Instance deletion (default: 10m)\n  }\n\n  # ... other configuration\n}\n```\n\nTimeouts apply to instances, block volumes, and security groups.\n\n## Lifecycle Protection\n\nTo protect critical resources from accidental deletion, use Terraform's `prevent_destroy` in your root module:\n\n```hcl\n# In your root module, after the module call:\nresource \"null_resource\" \"protect_database\" {\n  # Reference the database instances to create a dependency\n  triggers = {\n    instance_ids = join(\",\", [\n      for k, v in module.compute.instances : v.id\n      if startswith(k, \"database-\")\n    ])\n  }\n\n  lifecycle {\n    prevent_destroy = true\n  }\n}\n```\n\nAlternatively, for direct resource protection, fork the module and add:\n\n```hcl\n# In scaleway_instance_server.this resource:\nlifecycle {\n  prevent_destroy = true  # Add this line\n}\n```\n\n### Ignoring External Tag Changes\n\nSet `ignore_tags_changes = true` to prevent Terraform from detecting tag drift caused by external systems. Note: Due to Terraform limitations, this requires modifying the module source to add `ignore_changes = [tags]` to the lifecycle block.\n\n## License\n\nLicensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for full details.\n\nCopyright 2025 - This module is independently maintained and not affiliated with Scaleway.\n\n## Disclaimer\n\nThis module is provided \"as is\" without warranty of any kind. Use at your own risk.\n\n[apache]: https://opensource.org/licenses/Apache-2.0\n[apache-shield]: https://img.shields.io/badge/License-Apache%202.0-blue.svg\n[terraform-badge]: https://img.shields.io/badge/Terraform-%3E%3D1.10-623CE4\n[terraform-url]: https://www.terraform.io\n[scaleway-badge]: https://img.shields.io/badge/Scaleway%20Provider-%3E%3D2.64-4f0599\n[scaleway-url]: https://registry.terraform.io/providers/scaleway/scaleway/\n[release-badge]: https://img.shields.io/gitlab/v/release/leminnov/terraform/modules/scaleway-compute?include_prereleases\u0026sort=semver\n[release-url]: https://gitlab.com/leminnov/terraform/modules/scaleway-compute/-/releases\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftf-scaleway-modules%2Fterraform-scaleway-compute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftf-scaleway-modules%2Fterraform-scaleway-compute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftf-scaleway-modules%2Fterraform-scaleway-compute/lists"}