I am trying to provision a simple Ubuntu Linux VM with Terraform that allows users to connect with their Azure AD credentials. I am new to Terraform and am trying to I'm trying to find the right resource section/command that enables the "Login with Azure AD" setting from the GUI shown in the screenshot link below.
https://i.stack.imgur.com/Gg9p8.png
Here is a snippet of code that provisions the VM:
resource "azurerm_linux_virtual_machine" "dev" {
name = "devhost01"
resource_group_name = azurerm_resource_group.dev.name
location = azurerm_resource_group.ev.location
size = "Standard_D2s_v3"
admin_username = "admin"
network_interface_ids = [
azurerm_network_interface.dev.id,
]
admin_ssh_key {
username = "admin"
public_key = file("~/.ssh/admin.pub")
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
}
I have a related but secondary question as well; I am unsure if it warrants a separate question/post. I manually created a VM through the GUI enabling "Login with Azure AD", tried to connect with
az ssh vm --ip XXX.XXX.XXX.XXX
and received
Permission denied (publickey).
I haven't specified that users need to connect using ssh keys (at least not intentionally). Is there another section I need to add to allow basic SSH access for authenticated AD users?
To logon to a linux VM with Azure AD. You would need to perform below actions.
Install AAD linux extension, which appears to be installed as per your screenshot
Enable System assigned Managed Identity which facilitates the AD login. I see this also being created.
As mentioned in “Azure AD” section on your screenshot, you would need to assign one of Virtual Machine Administrator Login or Virtual Machine User Login roles via RBAC on the VM resource.
The third one is equally important like it’s predecessors to allow AD logins.
When all three steps are performed, az ssh vm --ip XXX.XXX.XXX.XXX would let you logon to the VM.
Update
---- adding tf code as requested in comments-----
add managed identity to VM resource
resource "azurerm_linux_virtual_machine" "dev" {
// blah-blah
identity {
type = "SystemAssigned"
}
}
add role assignment
resource "azurerm_role_assignment" "assign-vm-role" {
scope = azurerm_linux_virtual_machine.dev.id
role_definition_name = "Virtual Machine Administrator Login"
principal_id = <id-of-group/user/sp>
}
Related
I want to deploy with Terraform some Virtual machines inside Azure Stack Edge. Is it possible?
From the Azure documentation Here, I suspect that I can use the same Terraform code to create virtual machines in a Resource Group because it seems that they use the same Azure API, but I'm not sure.
If so, how could I adapt my code to use a Azure Stack Edge instead of Azure Resource group?
#Creating the VM
resource "azurerm_windows_virtual_machine" "jumphost" {
name = var.name
resource_group_name = data.azurerm_resource_group.jumphost.name
location = data.azurerm_resource_group.jumphost.location
size = "Standard_B2ms"
admin_username = "adminuser"
admin_password = data.azurerm_key_vault_secret.jumphost.value
network_interface_ids = [
azurerm_network_interface.jumphost.id,
]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
disk_size_gb = 127
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2022-Datacenter"
version = "latest"
}
}
This is an example how I deploy a VM.
Many Thanks
Both The Azure Stack Provider and Azure Provider are used to manage resources via the Azure Resource Manager API's..You can use the same terraform code to deploy resources in Azure Stack or AzureRM. Only you need to change the providers.
Below is screen shot from terraform registry.
Terraform, created by Microsoft partner HashiCorp, is using the same ARM REST APIs as a foundation.
For more information you can refer this Document
I have created some resources in Azure using Terraform and a Service principal:
A resource group
A virtual network
A virtual machine
Now, I need to create a virtual Gateway from this resource group and virtual network, but using a personal Azure account in the same Organization.
How can I add my user email as a Administrator to this resource group, from Terraform, using the Service Principal credentials?
You can use Terraform resource azurerm_role_assignment to add Owner permissions for your user to this resource group.
Example:
resource "azurerm_resource_group" "this" {
name = "example"
location = "West Europe"
}
resource "azurerm_role_assignment" "this" {
scope = azurerm_resource_group.this.id
role_definition_name = "Owner"
principal_id = "<Your user object id>"
}
I want to deploy some resources on Azure with Terraform.
On Azure, I have an account with "Owner rights" on one Resource Group only(RGName). Not at the subscription level.
From my linux server, I installed "az cli" and I did "az login". At this step, everything is OK.
The problem appears when I want to execute terraform to create one resource.
Content of provider.tf (the only one .tf file for now) :
provider "azurerm" {
}
If I do a "terraform plan", it works.
If I add the following line, it fails. Please see the error at the end :
resource "azurerm_virtual_network" "myterraformnetwork" {
name = "myVnet"
address_space = ["10.0.0.0/16"]
location = "eastus"
resource_group_name = "RGName"
tags = {
environment = "Terraform Demo"
}
}
I do not have right on subscription level but I do not need to.
With the Azure WebUI I can create resource on this Resource Group without problem.
The error :
Error: Error ensuring Resource Providers are registered: Cannot register provider Microsoft.DevSpaces with Azure Resource Manager: resources.ProvidersClient#Register: Failure responding to request: StatusCode=403 -- Original Error: autor
est/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client 'accountName' with object id 'IDaccountName' does not have authorization to perform action 'Microsoft.DevSpaces/r
egister/action' over scope '/subscriptions/subscriptionID' or the scope is invalid. If access was recently granted, please refresh your credentials.".
on provider.tf line 1, in provider "azurerm":
1: provider "azurerm" {
Thank you all !
If anyone else has this issue in a corporate (restricted) Azure environment, and doesn't have the patience to register the provider (which may not be necessary if you don't use the specified terraform resource) - have a look at https://github.com/terraform-providers/terraform-provider-azurerm/issues/4440
Specifically, this may help:
provider "azurerm" {
skip_provider_registration = "true"
It obviously won't help if you actually need the resource that fails to get registered (in our case it was Cannot register provider Microsoft.DevSpaces with Azure Resource Manager, but the resource will be variable depending on your environment and what Terraform decides to support)
For your issue, when you have the Owner role of the resource group, you can create new resources or manage the existing resources as you want. So permission is no problem. With the test on my side, it works well using a user has the Owner role of the resource group.
As the error shows, I think the possible reason is that you have multiple subscriptions in the tenant and the current subscription is not the right one which the user has the right permission. You can try to take a check and set the right subscription via the command:
az account set --subscription subscription_id
Thank you for your answer.
I got this when I execute "az account list" :
"cloudName": "AzureCloud",
"id": "***********0d43",
"isDefault": true,
"name": "BU*******",
"state": "Enabled",
"tenantId": "TENANTID",
"user": {
"name": "LOGINNAME",
"type": "user"
I do not have rights on this subscription but it is the only one that I know.
On Azure WebUI I can see that the RGName is on the same subscription.
This is a capture from Azure WebUI on the RGName :
Azure WebUI
Thank you
You may need to register the Resource provider by clicking on register as shown in below screenshot under subscription id.
Problem statement
I am trying to automatically map an Azure file share to Windows VMs using Azure VM extension. The VM extension installs successfully, the command runs but on logging into the VM I see that my drive is disconnected.
On trying to access it, I get an incorrect username or password error. However, running the PowerShell script on the machine correctly maps the network drive and I can access it.
Code
resource "azurerm_virtual_machine_extension" "test" {
# Custom VM extension documentation https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-windows
# additional documentation http://teknews.cloud/bootstrapping-azure-vms-with-terraform/, https://github.com/terraform-providers/terraform-provider-azurerm/issues/728
name = "network_share"
location = "${azurerm_resource_group.main.location}"
resource_group_name = "${azurerm_resource_group.main.name}"
#virtual_machine_name = "${azurerm_virtual_machine.vm.name}"
virtual_machine_name = "${element(azurerm_virtual_machine.vm.*.name, count.index)}"
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.9"
count = "${var.vm_count}"
settings = <<SETTINGS
{
"commandToExecute": "powershell -command \"[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${base64encode(data.template_file.net_fileshare_script.rendered)}')) | Out-File -filepath net_fileshare_script.ps1\" && powershell -File net_fileshare_script.ps1"
}
SETTINGS
depends_on = ["azurerm_virtual_machine.vm"]
}
data "template_file" "net_fileshare_script" {
template = "${file("./scripts/net_fileshare_script.ps1")}"
}
I found out the script works as it is. The problem is that the credentials for the storage share aren't available to the remote user once logged in.
Once the remote user logs in, running this command
Invoke-Expression -Command "cmdkey /add:storageaccount.file.core.windows.net /user:AZURE\storageaccount /pass:storagekey"
makes the storage share accessible to the remote user account.
NB: Is it possible to make a credential available to multiple user accounts via a one time script?
I tried the solutions above, but without success.
1 - I did it another way, I kept the powershell that makes the connection in storage
2 - I created a powershell script to create a windows task scheduler pointing to item 1
3 - In Terraform I created a line to execute the taskScheduller created in item
In Azure, I'm trying to create a Windows VM using Terraform. I have done this through Powershell previously using Template.json file. Now I have to do with terraform, which I'm completely new to. So I have searched for some Sample scripts which creates VM in Azure and found this.
In this link, there is a sample Terraform script to spin a Linux VM. But I need to spin a windows VM from an Image. Where should I give the Image details. My complete requirement is:
Create a Windows VM from an Image (have resource Id)
I already have Resource group, Virtual network, Subnet created. I just need to pass those values and create them.
We have already defined the Subnet address prefix, Vnet address space from the portal itself. So do I have to give again in the script or can I skip it.
The business requirement is that no VMs should have public IP and DNS name, So if I remove "# Create public IPs" section, will that not create public IP?
The script for creating a Linux machine is here, which I'm taking it as reference.
Below is an example of how to use data to use already existing resources in terraform, also there is a code block to create a windows VM. You will need to get the existing VNET and create a NIC
Use the data directive to get the VNET azurerm_virtual_network, you can see the syntax below for the resource group. You will need to add the resource group and possibly location into this block.
Create a azurerm_network_interface resource using the VNET ID
Add the network interface ID to the VM (network_interface_ids = [])
Example TF Code to Create and load balance VMs
variable "subscription_id" {}
variable "client_id" {}
variable "client_secret" {}
variable "tenant_id" {}
provider "azurerm" {
tenant_id = "${var.tenant_id}"
subscription_id = "${var.subscription_id}"
client_id = "${var.client_id}"
client_secret = "${var.client_secret}"
}
data "azurerm_resource_group" "resource_group" {
name = "learning-tf-web-rg"
}
resource "azurerm_virtual_machine" "web_server" {
name = "server"
location = "westus2"
resource_group_name = "${data.azurerm_resource_group.resource_group.name}"
network_interface_ids = []
vm_size = "Standard_B2s"
storage_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2016-Datacenter-Server-Core-smalldisk"
version = "latest"
}
storage_os_disk {
name = "server-os"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "server"
admin_username = "server"
admin_password = "Passw0rd1234"
}
os_profile_windows_config {
}
}
From Terraform's perspective, a Windows VM is really quite similar to a Linux VM. The #1 difference in my opinion is that the Windows VM requires a os_profile_windows_config attribute, while the Linux VM needs os_profile_linux_config.
The TF code you found on the Microsoft site is a fine start. Additionally, you may look in the Terraform Registry. For example, here's a module for a Linux VM.
I strongly recommend reading through all of the options in the VM resource. I know it's a lot, but you should understand what choices you have.
Lastly, there's no substitute for writing some code and testing it. If you do something wrong, either Terraform and/or the Azure API will tell you, and if it's unclear, a web search will pop up an answer or a pointer in the right direction.