0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

azureでmysql接続

0
Posted at

Plaintext
[ インターネット ]
│ (一切アクセス拒否!)
▼
┌─【 my-vnet (仮想ネットワーク) 】────────────────────────┐
│ │
│ ┌─ [container-subnet] ─┐ ┌─ [mysql-subnet] ───┐ │
│ │ │ │ │ │
│ │ Container App (Web) ┼─────>┼─> MySQL Server │ │
│ │ │ VNet │ (appdb) │ │
│ └──────────────────────┘ 内部 └────────────────────┘ │
│ 通信 │
│ ┌─ [vm-subnet] ────────┐ ▲ │
│ │ テスト用VM ┼──────┘ │
│ └──────────────────────┘ │
└─────────────────────────────────────────────────────────┘

これを実現するterraform(今回はnginx)

main.tf
 # ==================== プロバイダー設定 ====================
# Azureの操作に必要なプラグインの定義(features ブロックが必須です)
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 3.0" # または 4.x
    }
    tls = {
      source  = "hashicorp/tls"
      version = "~> 4.0"
    }
    local = {
      source  = "hashicorp/local"
      version = "~> 2.0"
    }
  }
}

provider "azurerm" {
  features {} # 👈 これが不足していたためエラーになっていました
}

# ==================== リソースグループ ====================
resource "azurerm_resource_group" "rg" {
  name     = "my-app-rg"
  location = "japaneast"
}

# ==================== SSH鍵の自動生成 ====================
resource "tls_private_key" "vm_key" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "local_file" "private_key" {
  content         = tls_private_key.vm_key.private_key_pem
  filename        = "${path.module}/vm_private_key.pem"
  file_permission = "0400"
}

# ==================== VNet & Subnets ====================
resource "azurerm_virtual_network" "vnet" {
  name                = "my-vnet"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  address_space       = ["10.0.0.0/16"]
}

# ACA用サブネット:仕様に合わせて最低要件の /23 に拡張
resource "azurerm_subnet" "container_subnet" {
  name                 = "container-subnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.0.0/23"]

  delegation {
    name = "ContainerApps"
    service_delegation {
      name    = "Microsoft.App/environments"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"]
    }
  }
}

# Bastion用サブネット
resource "azurerm_subnet" "bastion_subnet" {
  name                 = "AzureBastionSubnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.2.0/26"]
}

# MySQL用サブネット
resource "azurerm_subnet" "mysql_subnet" {
  name                 = "mysql-subnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.3.0/24"]

  delegation {
    name = "MySQLFlexible"
    service_delegation {
      name    = "Microsoft.DBforMySQL/flexibleServers"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"]
    }
  }
}

# テスト用VM専用サブネット
resource "azurerm_subnet" "vm_subnet" {
  name                 = "vm-subnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.4.0/24"]
}

# ==================== Private DNS ====================
resource "azurerm_private_dns_zone" "mysql" {
  name                = "privatelink.mysql.database.azure.com"
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_private_dns_zone_virtual_network_link" "mysql_link" {
  name                  = "mysql-vnet-link"
  resource_group_name   = azurerm_resource_group.rg.name
  private_dns_zone_name = azurerm_private_dns_zone.mysql.name
  virtual_network_id    = azurerm_virtual_network.vnet.id
}

# ==================== Log Analytics ====================
resource "azurerm_log_analytics_workspace" "main" {
  name                = "my-app-logs"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  sku                 = "PerGB2018"
}

# ==================== MySQL ====================
resource "azurerm_mysql_flexible_server" "mysql" {
  # 【重要】他のユーザーと重複しないよう、末尾に独自の文字列を入れてください
  name                          = "my-mysql-private-server-999" 
  resource_group_name           = azurerm_resource_group.rg.name
  location                      = azurerm_resource_group.rg.location
  administrator_login           = "mysqladmin"
  administrator_password        = "P@ssw0rd-ChangeMe123!"
  sku_name                      = "GP_Standard_D2ds_v4"
  version                       = "8.0.21"

  delegated_subnet_id = azurerm_subnet.mysql_subnet.id
  private_dns_zone_id = azurerm_private_dns_zone.mysql.id

  depends_on = [azurerm_private_dns_zone_virtual_network_link.mysql_link]
}

resource "azurerm_mysql_flexible_database" "main" {
  name                = "appdb"
  resource_group_name = azurerm_resource_group.rg.name
  server_name         = azurerm_mysql_flexible_server.mysql.name
  charset             = "utf8mb4"
  collation           = "utf8mb4_unicode_ci"
}

# ==================== Azure Bastion ====================
resource "azurerm_public_ip" "bastion_ip" {
  name                = "bastion-ip"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  allocation_method   = "Static"
  sku                 = "Standard"
}

resource "azurerm_bastion_host" "bastion" {
  name                = "my-bastion"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location

  ip_configuration {
    name                 = "config"
    subnet_id            = azurerm_subnet.bastion_subnet.id
    public_ip_address_id = azurerm_public_ip.bastion_ip.id
  }
}

# ==================== テスト用 Linux VM ====================
resource "azurerm_network_interface" "vm_nic" {
  name                = "test-vm-nic"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.vm_subnet.id
    private_ip_address_allocation = "Dynamic"
  }
}

resource "azurerm_linux_virtual_machine" "test_vm" {
  name                = "test-vm"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  size                = "Standard_B2s"
  admin_username      = "azureuser"

  network_interface_ids = [azurerm_network_interface.vm_nic.id]

  admin_ssh_key {
    username   = "azureuser"
    public_key = tls_private_key.vm_key.public_key_openssh
  }

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }

  user_data = base64encode(<<-EOF
              #!/bin/bash
              apt-get update
              apt-get install -y mysql-client

              mkdir -p /opt/mysql
              curl -sL https://dl.cacerts.digicert.com/DigiCertGlobalRootG2.crt.pem -o /opt/mysql/DigiCertGlobalRootG2.crt.pem
              chmod 644 /opt/mysql/DigiCertGlobalRootG2.crt.pem
              EOF
  )
}

# ==================== Container App ====================
resource "azurerm_container_app_environment" "cae" {
  name                       = "my-cae"
  resource_group_name        = azurerm_resource_group.rg.name
  location                   = azurerm_resource_group.rg.location
  infrastructure_subnet_id   = azurerm_subnet.container_subnet.id
  log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id

  depends_on = [azurerm_private_dns_zone_virtual_network_link.mysql_link]
}

resource "azurerm_container_app" "app" {
  name                         = "my-web-app"
  resource_group_name          = azurerm_resource_group.rg.name
  container_app_environment_id = azurerm_container_app_environment.cae.id
  revision_mode                = "Single"

  ingress {
    external_enabled = true
    target_port      = 80
    transport        = "http"

    traffic_weight {
      latest_revision = true
      percentage      = 100
    }
  }

  template {
    container {
      name   = "nginx"
      image  = "nginx:latest"
      cpu    = 0.5
      memory = "1Gi"
    }
  }
}

# ==================== OUTPUT ====================
output "bastion_public_ip" {
  value = azurerm_public_ip.bastion_ip.ip_address
}

output "vm_private_ip" {
  value = azurerm_network_interface.vm_nic.private_ip_address
}

output "container_app_url" {
  value = "https://${azurerm_container_app.app.latest_revision_fqdn}"
}

output "db_host" {
  value = azurerm_mysql_flexible_server.mysql.fqdn
}

output "private_key_path" {
  value       = local_file.private_key.filename
  description = "VMにSSHするための秘密鍵のパス"
}

bastionに接続する方法

cp vm_private_key.pem /mnt/c/Users/Public/Documents/

vmにbastionに接続する方法
2. Azureポータルの画面でファイルを選ぶ
青い 「ファイルの選択」 ボタンを押します。

Windowsのファイル選択画面が開くので、以下の順番でフォルダをたどってください。

PC > ローカルディスク (C:) > ユーザー > パブリック > パブリックのドキュメント

その中に vm_private_key.pem が入っているので、それを選んで「開く」を押します。

Windowsのアクセス拒否エラー(権限の罠)に引っかかることなく、きれいにファイルを読み込ませることができます!

ユーザー名を azureuser に直して、パスフレーズは空欄にした状態で、青くなった「接続」ボタン。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?