Terraform을 사용하여 프라이빗 Azure Cloud Shell 배포
9620 단어 cloudshellazureprivateterraform
상상할 수 있듯이 솔루션은 실행되는 컨테이너가 프라이빗 리소스에 액세스할 수 있는 방식으로 Cloud Shell을 Azure 가상 네트워크에 배포하는 것입니다. 이 솔루션은 또한 Cloud Shell이 사용자 프로필 및 데이터에 사용하는 백업 스토리지 계정을 보호하여 잠긴 환경으로 끝납니다.
다음 다이어그램은 솔루션 아키텍처를 보여줍니다.
솔루션, 서비스 및 제한 사항에 대한 자세한 정보가 필요한 경우 여기에서 설명서를 확인하십시오: Cloud Shell in an Azure Virtual Network .
이제 terraform을 사용하여 Cloud Shell을 비공개로 만드는 방법을 살펴보겠습니다.
Terraform을 사용하여 프라이빗 Azure Cloud Shell 배포
If Cloud Shell has been used in the past, the existing clouddrive must be unmounted. To do this run
clouddrive unmount
from an active Cloud Shell session.
1. 다음 내용으로 provider.tf 파일을 생성합니다.
terraform {
required_version = ">= 0.13.5"
}
provider "azurerm" {
version = "= 2.46.1"
features {}
}
provider "azuread" {
version = "= 1.3.0"
}
provider "http" {
version = "= 2.0.0"
}
우리는
azurerm
를 사용하여 Azure 서비스를 배포하고, azuread
를 사용하여 일부 서비스 주체 정보를 가져오고, http
를 사용하여 현재 공용 IP 주소를 가져오므로 사용자만 Cloud Shell에 연결할 수 있습니다.2. 다음 내용으로 variables.tf 파일을 생성합니다.
variable location {
default = "west europe"
}
variable resource_group {
default = "<resource group name>"
}
variable "vnet_name" {
default = "<vnet name>"
}
variable sa_name {
default = "<Backing Storage Account name>"
}
variable relay_name {
default = "<Azure Relay name>"
}
자리 표시자를 사용하려는 기본값으로 바꿔야 합니다.
3. 다음 내용으로 main.tf 파일을 생성합니다.
# Get Azure Container Instance Service Principal. Amazing right? Cloud Shell uses this Service Principal!
data "azuread_service_principal" "container" {
display_name = "Azure Container Instance Service"
}
# Create Resource Groupto hold the resources.
resource "azurerm_resource_group" "rg" {
name = var.resource_group
location = var.location
}
# Create a VNET.
resource "azurerm_virtual_network" "vnet" {
name = var.vnet_name
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
# Create a Containers Subnet. Here is where Cloud Shell will run.
resource "azurerm_subnet" "containers" {
name = "cloudshell-containers"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.0.0/24"]
# Delegate the subnet to "Microsoft.ContainerInstance/containerGroups".
delegation {
name = "cloudshell-delegation"
service_delegation {
name = "Microsoft.ContainerInstance/containerGroups"
}
}
# Add service enpoint so Cloud Shell can reach Storage Accounts. At the moment the solution does not work with Private Enpoints for the Storage Account.
service_endpoints = ["Microsoft.Storage"]
}
# Create a subnet to host Azure Relay service.
resource "azurerm_subnet" "relay" {
name = "relay"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.1.0/24"]
enforce_private_link_endpoint_network_policies = true
}
# Create a network profile for the Cloud Shell containers.
resource "azurerm_network_profile" "networkprofile" {
name = "cloudshell"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
container_network_interface {
name = "cloudshell-containers"
ip_configuration {
name = "ipconfig"
subnet_id = azurerm_subnet.containers.id
}
}
}
# Assign Network Contributor to the Azure Container Instance Service Principal.
resource "azurerm_role_assignment" "network_contributor" {
scope = azurerm_network_profile.networkprofile.id
role_definition_name = "Network Contributor"
principal_id = data.azuread_service_principal.container.object_id
}
# Create an Azure Relay namespace.
resource "azurerm_relay_namespace" "relay" {
name = var.relay_name
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
sku_name = "Standard"
}
# Add a private enpoint to the Azure Relay namespace.
resource "azurerm_private_endpoint" "endpoint" {
name = "cloudshell-privateendpoint"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
subnet_id = azurerm_subnet.relay.id
private_service_connection {
name = "privateendpoint"
private_connection_resource_id = azurerm_relay_namespace.relay.id
is_manual_connection = false
subresource_names = ["namespace"]
}
}
# Assign Contributor to the Azure Container Instance Service Principal.
resource "azurerm_role_assignment" "contributor" {
scope = azurerm_relay_namespace.relay.id
role_definition_name = "Contributor"
principal_id = data.azuread_service_principal.container.object_id
}
# Create the Storage Account to hold the Cloud Shell profiles.
resource "azurerm_storage_account" "sa" {
name = var.sa_name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "GRS"
enable_https_traffic_only = true
}
# Create a file share to hold the user profiles.
resource "azurerm_storage_share" "share" {
name = "profile"
storage_account_name = azurerm_storage_account.sa.name
quota = 6
}
# Get your current public IP.
data "http" "current_public_ip" {
url = "http://ipinfo.io/json"
request_headers = {
Accept = "application/json"
}
}
# Protect the Storage Account setting the firewall.
# This is done only after the file share is created.
resource "azurerm_storage_account_network_rules" "sa_rules" {
resource_group_name = azurerm_resource_group.rg.name
storage_account_name = azurerm_storage_account.sa.name
default_action = "Deny"
virtual_network_subnet_ids = [azurerm_subnet.containers.id]
# ip_rules = [
# jsondecode(data.http.current_public_ip.body).ip
# ]
depends_on = [
azurerm_storage_share.share
]
}
# Create DNS Zone for Relay
resource "azurerm_private_dns_zone" "private" {
name = "privatelink.servicebus.windows.net"
resource_group_name = azurerm_resource_group.rg.name
}
# Create A record for the Relay
resource "azurerm_private_dns_a_record" "relay" {
name = var.relay_name
zone_name = azurerm_private_dns_zone.private.name
resource_group_name = azurerm_resource_group.rg.name
ttl = 3600
records = [azurerm_private_endpoint.endpoint.private_service_connection[0].private_ip_address]
}
# Link the Private Zone with the VNet
resource "azurerm_private_dns_zone_virtual_network_link" "relay" {
name = "relay"
resource_group_name = azurerm_resource_group.rg.name
private_dns_zone_name = azurerm_private_dns_zone.private.name
virtual_network_id = azurerm_virtual_network.vnet.id
}
# Open the relay firewall to local IP
resource "null_resource" "open_relay_firewall" {
provisioner "local-exec" {
interpreter = ["powershell"]
command = "az rest --method put --uri '${azurerm_relay_namespace.relay.id}/networkrulesets/default?api-version=2017-04-01' --body '{\"properties\":{\"defaultAction\":\\\"Deny\\\",\"ipRules\":[{\"ipMask\":\\\"${jsondecode(data.http.current_public_ip.body).ip}\\\"}],\"virtualNetworkRules\":[],\"trustedServiceAccessEnabled\":false}}'"
}
depends_on = [
data.http.current_public_ip,
azurerm_relay_namespace.relay
]
}
4. 솔루션 배포:
다음 명령을 실행합니다.
terraform init
terraform plan -out tf.plan
terraform apply ./tf.plan
도움이 되길 바랍니다! 전체 코드here를 찾으십시오.
Reference
이 문제에 관하여(Terraform을 사용하여 프라이빗 Azure Cloud Shell 배포), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/cmendibl3/deploy-a-private-azure-cloud-shell-with-terraform-5727텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)