# MySQL Database (Private)

Deploys a single MySQL server on a private network with no public access. Designed to be used as a backend database for application stacks or accessed via VPN or jump server.

#### Architecture:

* 1 Instance (NanoBoost — 2 vCPU, 4 GB RAM)
* 1 private network
* 50 GB boot volume
* No floating IP
* Security group allows 3306 from private subnet, 22 from private subnet

#### What is automated:

* Instance creation with selected flavor and image
* Private network, subnet, and router
* Floating IP assigned to Instance&#x20;
* Security group: port 22 (public), port 3306 (10.200.0.0/24 only), ICMP (subnet only)
* MySQL 8.0 installed and configured
* Bind address set to 0.0.0.0 (access controlled by security group)
* Random root password generated and saved

#### Before you launch:

Update these parameters in the template or at launch time:

| Parameter        | Default                | What to change                                                                 |
| ---------------- | ---------------------- | ------------------------------------------------------------------------------ |
| `key_name`       | `stack-test`           | **Required.** Replace with your SSH keypair name from **Compute - Key Pairs**. |
| `image`          | `Ubuntu 22.04 Updated` | Change only if you need a different OS image.                                  |
| `flavor`         | `NanoBoost`            | Change only if you want a different Instance size.                             |
| `volume_size`    | `50`                   | Increase for larger databases (in GB).                                         |
| `public_network` | `Public`               | Do not change unless your cloud has a different external network name.         |

{% hint style="info" %}
**key\_name is the only parameter you must change before launching.** Everything else works with defaults.
{% endhint %}

#### MySQL Template

Save as `mysql-private.yaml` and upload via Orchestration or Past Direct.

```
heat_template_version: 2021-04-16
description: >
  NeevCloud: MySQL Database Server (Private). DB port 3306 restricted to
  subnet CIDR only. SSH access via floating IP for administration.

parameters:
  image:
    type: string
    default: Ubuntu 22.04 Updated
  flavor:
    type: string
    default: NanoBoost
  volume_size:
    type: number
    description: Boot volume size in GB
    default: 50
  public_network:
    type: string
    default: Public
  key_name:
    type: string
    default: stack-test

resources:
  net:
    type: OS::Neutron::Net
    properties:
      name: mysql-net

  subnet:
    type: OS::Neutron::Subnet
    properties:
      network: { get_resource: net }
      cidr: 10.200.0.0/24
      dns_nameservers: [8.8.8.8, 8.8.4.4]

  router:
    type: OS::Neutron::Router
    properties:
      external_gateway_info:
        network: { get_param: public_network }

  router_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router: { get_resource: router }
      subnet: { get_resource: subnet }

  sg:
    type: OS::Neutron::SecurityGroup
    properties:
      name: mysql-sg
      rules:
        - { direction: ingress, protocol: tcp, port_range_min: 22, port_range_max: 22, remote_ip_prefix: 0.0.0.0/0 }
        - { direction: ingress, protocol: tcp, port_range_min: 3306, port_range_max: 3306, remote_ip_prefix: 10.200.0.0/24 }
        - { direction: ingress, protocol: icmp, remote_ip_prefix: 10.200.0.0/24 }

  server:
    type: OS::Nova::Server
    properties:
      name: mysql-server
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
      networks:
        - network: { get_resource: net }
      security_groups:
        - { get_resource: sg }
      block_device_mapping_v2:
        - boot_index: 0
          delete_on_termination: true
          image: { get_param: image }
          volume_size: { get_param: volume_size }
      user_data_format: RAW
      user_data: |
        #!/bin/bash
        set -e
        export DEBIAN_FRONTEND=noninteractive

        DB_ROOT_PASS=$(openssl rand -hex 16)

        apt-get update -y
        apt-get install -y mysql-server

        # Bind to all interfaces for private network access
        sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
        systemctl restart mysql

        mysqladmin -u root password "${DB_ROOT_PASS}"
        systemctl enable mysql

        cat > /root/.db_credentials <<EOF
        MySQL Root Password: ${DB_ROOT_PASS}
        Bind Address: 0.0.0.0 (access restricted via security group to 10.200.0.0/24)
        Port: 3306
        EOF
        chmod 600 /root/.db_credentials

  fip:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network: { get_param: public_network }

  fip_assoc:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id: { get_resource: fip }
      port_id: { get_attr: [server, addresses, { get_resource: net }, 0, port] }

outputs:
  floating_ip:
    description: Public IP (SSH access only)
    value: { get_attr: [fip, floating_ip_address] }
  private_ip:
    description: Private IP (use this for DB connections from other VMs on same network)
    value: { get_attr: [server, first_address] }
  credentials_note:
    description: Database credentials location
    value: "SSH into server and run: cat /root/.db_credentials"
```

#### Access:

* SSH: only from another Instance on the same private network
* MySQL: connect from application instance at private-ip:3306
* Credentials: `sudo cat /root/.db_credentials`

#### Deploy:

1. Go to [Orchestration](/neevcloud-products/orchestration-infrastructure-as-code/web-server-stack-template.md)
2. Upload mysql-private.yaml
3. Select keypair, flavor, image
4. Launch stack

{% hint style="info" %}
Port 3306 is not accessible from the internet. Connect from other VMs on the same 10.200.0.0/24 network, or use SSH tunneling.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.neevcloud.com/neevcloud-guide/stack-automation-library/databases/mysql-database-private.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
