ARM template deployment scripts Azure login - arm-template

I'm trying to use a Microsoft.Resources/deploymentScripts in my ARM template that will execute some Azure Powershell commands.
Obviously, without specifying any identity attribute, I need to run Connect-AzAccounts in my script.
My question is, how can I retrieve the Service Principal credentials and pass this to my ARM DeploymentScripts?

I'm assuming that the identity you're using to deploy your ARM (the "Deployment Principal") is the same as the one running your Deployment Script (the "Deployment Script Principal"). See this link.
Here's what I did. I specify the "Deployment Service Principal" credentials as ARM parameters, and then pass these to the Deployment Script as secure environment variables (I, too, am using one Principal for both the ARM and the Deployment Script).
This does mean that my ARM Deployment pipeline looks more or less like this:
az login --service-principal -u ${appId} -p ${clientSecret} ...
az deployment group create ... --parameters appId=${appId} clientSecret=${clientSecret}
In other words: I'm specifying the Service Principal Credentials twice:
to login using the Deployment Principal
to pass the Deployment Principal credentials to the Deployment Script
Assuming az login doesn't cache your Service Principal Credentials (let's hope it doesn't!), there is no way to 'fetch' those credentials dynamically, I think.

Related

How can I terraform granting access to my Azure Active Directory Tenant

Input: client_id, subscription_id, resource-group-name, .
Manual / command line steps:
Approving at
https://login.microsoftonline.com/<tenant-id>/oauth2/authorize?client_id=<client_id>&response_type=code
Creating a new role (az role definition create --output none --role-definition)
Creating a role assignment (az role assignment create).
Steps 2-3 are pretty easy since I could leverage azurerm TF Provider and, more speficially, its azurerm_role_definition and azurerm_role_assignment resources but I'm kinda confused about step #1.
Update: after googling it seems like step #1 is very similar to Enable Azure Active Directory in your App Service app if that helps.
Before you can even get Terraform to interact with Azure/Azure AD resources you need to get Terraform to authenticate to it.
If you're running your Terraform code locally, the process is generally to authenticate using the Azure CLI - az login and then you provide the code shown by the CLI, to the authentication page.
If you want to do this non-interactively, the best practice is you'd need to get the Terraform code run on a machine that either has Managed Identities enabled. Either a System-Assigned or a User-Assigned identity.
Another possible but less direct approach would be to use a Service Principal with a Client Secret for Terraform to authenticate. this is kinda like the link you provided for the App Service.
Try to follow the steps in those two links above as these are from Terraform and have all required steps to ensure you are able to set it up right.

Terraform authentication multi-subscription using multiple service principals

I want my terraform scripts to be able to authenticate on multiple azure subscriptions using multiple service principal.
Here is what I think:
Create a service principal (App registration).
Deploy terraform scripts in azure container instances
Give the "contributor" role to my service principal on the subscription (x)
Configure terraform scripts with environment variables to select the right credentials when I want to create resources in this subscription.
$ export ARM_SUBSCRIPTION_ID=159f2485-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Client subscription
$ export ARM_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # client_id of the service principal
$ export ARM_CLIENT_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
$ export ARM_TENANT_ID=72f988bf-xxxx-xxxx-xxxx-xxxxxxxxxxxx # the same tenant for all clients
Is this correct?
Do you have a more secure way to authenticate on multiple subscriptions when using terraform cloud? (ideally without client_secret)
If the container instance can run Terraform script, then there is no problem with the steps. You give permission to the service principal and change the environment variable ARM_SUBSCRIPTION_ID for different subscriptions, then Terraform script works for different subscriptions.
A safer way is to use the authentication with Azure CLI. If you set different subscriptions with the CLI command:
az account set --subscription="SUBSCRIPTION_ID"
Then the Terraform script will also work for different subscriptions. In this way you don't need to set the secret as the environment variable.

Using Azure-Cli to deploy an azure function to azure from Jenkins

I have created a docker container and generated final artifact of my azure function app code. Azure Cli is already installed in the container. Is it possible to deploy to Azure using Azure Cli and pass the credentials along?
I tried the following command (example credentials):
az functionapp deployment user set --user-name "MY_USER" --password "MY_PASS" --subscription "MY_SUBSCRIPTION"
But it results in the following error:
Subscription 'MY_SUBSCRIPTION' not recognized. ValidationError: Please run 'az login' to setup account.
If I login (which requires entering a pass code to a browser), then the command above seems to be working.
This is going to be part of CI/CD and manual login is not a solution. Any ideas?
You would need to use a service principle to authenticate. But since you mentioned you are using Jenkins, fortunately there are rich set of plugins available for different Azure resources which can handle the authentication for you if you setup in your Jenkins dashboard. For example, in this case you are using az cli for which you can install https://plugins.jenkins.io/azure-cli/
Yes, you need to be authenticated. Here you have several authentication options: Sign in with Azure CLI
Authenticating with a service principal is the best way to write secure scripts or programs
Sign in with a service principal

Using Azure API without login (using roles)

I'm trying to list virtual machines in azure from inside another virtual machine in azure. I mean, what I want to do is list backend members from the frontent. BUT I don't want to use credentials in my front end and I want to use roles.
For example, in AWS you can assign roles (EC2::DescribeInstance) to instances and use this command:
aws ec2 describe-instances --query 'Reservations[].Instances[].[PrivateIpAddress]' --output text --filters Name=instance-state-name,Values=running Name=tag:myapp-member,Values=myapp-backend
I can run that command without expose my credentials in any place.
If I run something like this on Azure
az vm list
It says I need to login first.
And I can't find how to assign roles to the instance.
Thanks a lot
Cheers
For your purpose, you can use the VM Managed Identity to log in for the Azure CLI, this way will not store any credential in the VM. But first, you need to assign the roles to your VM. And to assign the roles, you can use the Azure CLI command az role assignment create and the steps in Assign a managed identity access to a resource using Azure CLI. Or just in the Azure Portal, you can follow the steps in Assign a managed identity access to a resource by using the Azure portal. The PowerShell command is also available.
When the role is created, you can use the Azure CLI command az login --identity to log in without credential.
Note: You need to install the Azure CLI in the VM first.

Using Azure CLI in Jenkins pipeline

I'm trying to use the Jenkins pipeline with Azure using this tutorial: https://learn.microsoft.com/en-us/azure/jenkins/execute-cli-jenkins-pipeline with the exception that I have Jenkins on localhost (running Win7).
The build works as expected, but deployment fails on the line in Jenkinsfile where the 'az login...' script should run, with a 'command not found' error.
withCredentials([azureServicePrincipal('...')]) {
sh '''
'az login ..'
I am able to use the 'az' commands in the command line outside of Jenkins.
Am I missing something? Any help would be appreciated.
You need to add Azure service principal to Jenkins credential. Please refer to the link you provided.
If you don't have a service principal, you could use Azure CLI 2.0 to create a new. Please refer to this link:Create an Azure service principal with Azure CLI 2.0.
withCredentials([azureServicePrincipal('<mySrvPrincipal>')])
<mySrcvPrincipal> is credential id you set.
Note:
When you add Azure service principal to Jenkins credential, click Verify Service Principal, please ensure you also see Successfully verified the Microsoft Azure Service Principal.

Resources