Calling Terraform from Ansible - azure

When i am using terraform modules directly being called from shell scripts it works fine.
But when i am wrapping same shell script which is called from an ansible task it fails. validated all the environment variables for ARM credentials which are being passed. All are fine, but somehow not getting any success to run terraform as an ansible task.
Below is the error I get
Error refreshing state: 1 error(s) occurred:\n\n* module.oracle_server.provider.azurerm: Unable to list provider registration status, it is possible that this is due to invalid credentials or the service principal does not have permission to use the Resource Manager API, Azure error: azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://management.azure.com/subscriptions/****/providers?api-version=2016-02-01: StatusCode=0 -- Original Error: adal:
UPDATEd by the editor
Please update your ansible codes here, more than in comment, lost all format.
- name: Terraform Module
terraform:
project_path: "{{ terraform_module_path }}"
state: "{{ item.infra_state }}"
variables:
platform: "{{ platform }}"
application_name: "{{ application_name }}"
environment: "{{ env }}"

From the error message, it can't properly set the azure credentials, so please check if you include the provider codes or not.
# Configure the Azure Provider
provider "azurerm" {
# whilst the `version` attribute is optional, we recommend pinning to a given version of the Provider
version = "=1.21.0"
}
Reference: https://www.terraform.io/docs/providers/azurerm/

Related

How to set KUBECONFIG from terraform cloud generate file in github actions

I am trying to set up github actions to run a CI with terraform and kubernetes. I am connecting to terraform cloud to run the terraform commands and it appears to be generating the kubeconfig during the apply process. I get this in the outout:
local_file.kubeconfig: Creation complete after 0s
In the next step, I try to run kubectl to see the resources that were built, but the command fails because it can't find the the configuration file. Specifically:
error: Missing or incomplete configuration info.
So my question is, how do I use the newly generated local_file.kubeconfig in my kubectl commands?
My first attempt was to expose the KUBECONFIG as an environment variable in the github action step, but I didn't know how I would get the value from terraform cloud into the github actions. So instead, I tried to set the variable in my terraform file with a provisioner definition. But this doesn't seem to work.
Is there an easier way to load that value?
Github Actions Steps
steps:
- name: Checkout code
uses: actions/checkout#v2
with:
ref: 'privatebeta-kubes'
- name: Setup Terraform
uses: hashicorp/setup-terraform#v1
with:
cli_config_credentials_token: ${{ secrets.TERRAFORM_API_TOKEN }}
- name: Terraform Init
run: terraform init
- name: Terraform Format Check
run: terraform fmt -check -v
- name: Terraform Plan
run: terraform plan
env:
LINODE_TOKEN: ${{ secrets.LINODE_TOKEN }}
- name: Terraform Apply
run: terraform apply -auto-approve
env:
LINODE_TOKEN: ${{ secrets.LINODE_TOKEN }}
# this step fails because kubectl can't find the token
- name: List kube nodes
run: kubectl get nodes
and my main.tf file has this definition:
provider "kubernetes" {
kubeconfig = "${local_file.kubeconfig.content}"
}

ansible failed with 'dict object' has no attribute 'ipAddress

I was trying to provision an Azure application gateway by referring to the below document. https://learn.microsoft.com/en-us/azure/developer/ansible/application-gateway-configure?tabs=ansible but instead of containers I have used a virtual machine as my backend pool.
- name: Get info of backend server 1
azure_rm_resource_info:
api_version: '2018-04-01'
resource_group: "{{ resource_group }}"
provider: compute
resource_type: virtualmachines
resource_name: "{{ vm_1_name }}"
register: vm_1_output
- name: Create instance of Application Gateway
azure_rm_appgateway:
resource_group: "{{ resource_group }}"
name: "{{ appgw_name }}"
frontend_ip_configurations:
- public_ip_address: "publicip-{{env}}-{{appgw_name}}"
name: appGatewayFrontendIP
frontend_ports:
- port: 80
name: appGatewayFrontendPort
backend_address_pools:
- backend_addresses:
- ip_address: "{{ vm_1_output.response[0].properties.ipAddress.ip }}"
name: appGatewayBackendPool
But am getting the below error.
"The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'ipAddress'\n\nThe error appears to be in
I have tried changing the values IpAddress.ip, IPAddress.ip and private_ip_address.id but but still failing. Any help will be much appreciated.
Thanks
Looking at the return values for the azure_rm_resource_info module in Ansible, there doesn't seem to be an ipaddress property being returned in the response.
Use the azure_rm_networkinterface_info module to get facts for the network interface attached to the VM for retrieving the IP address. You should then be able to get to the IP with an expression similar to: networkinterface_output.networkinterfaces[0].ip_configurations[0].private_ip_address
Check this SO post that discusses a similar issue.

Unable to encrypt Azure storage account using ansible

I am unable to set encryption for the storage account once the storage account created successfully. I am creating the below playbooks for the storage account and encryption.
- name: storage_account_creation | deploy storage account
azure_rm_storageaccount:
state: present
cloud_environment: "AzureCloud"
subscription_id: "XXXX-XXXX-XXXX-XXX"
resource_group_name: "XXXX-XXXX-XXXX-XXXX"
client_id: "XXXX-XXXX-XXXX-XXXX"
secret: "XXXX-XXXX-XXXX-XXXX"
tenant: "XXXX-XXXX-XXXX-XXX"
location: "{{ azloc['stdout_lines'][0] }}"
kind: BlobStorage
access_tier: "Hot"
name: "storageaccount_001"
account_type: "Standard_LRS"
network_acls:
bypass: AzureServices
default_action: deny
encrypt.yml
- name: encrypt | Get keyvault name from id
set_fact:
keyvaultname: "XXXXXXXXXX"
- name: encrypt | Get object id of storage account
shell: az storage account show --subscription "{{ subscription_id }}" -n "{{ Storageaccount_name }}" --query "identity.principalId" --output tsv
register: azsaobjectid
- debug:
var: azsaobjectid
- name: encrypt | Create key vault access policy for new storage account
shell: az keyvault set-policy --subscription "{{ subscription_id }}" -n {{ keyvaultname }}" --key-permissions get wrapKey unwrapKey --object-id "{{ azsaobjectid.stdout_lines[0] }}"
When I execute the scripts I get the below error
fatal: [localhost]: FAILED! =>
msg: |-
The task includes an option with an undefined variable. The error was: list object has no element 0
The error appears to be in 'encrypt.yml': line 10, column 4, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: encrypt | Create key vault access policy for new storage account
^ here
The error details suggest that you are using a variable that hasn't been defined. I suspect this is from your register block in get object id of storage account.
However...
Consider re-writing these tasks to use official azure modules.
Shelling out should be a last resort, and from the look of it, you can accomplish your goal by using the azure_rm_storageaccount_info_module module to gather facts, and azure_rm_keyvault module to set your policy.
Using official modules ensures your playbook is idempotent, easier to read, and your error details will likely become clearer as well.

Ansible - How to run YAML code in Azure Cloud Shell

Question: How do I run the following YAML in Azure Cloud Shell?
In step 1 of this Ansible tutorial, the author is asking to run the following YAML - to create a resource group. I'm using PowerShell in Azure Cloud Shell (where Ansible is pre-installed).
- name: Create resource group
azure_rm_resourcegroup:
name: rg-cs-ansible
location: eastus
Save it to a playbook.yaml text file and run it with ansible-playbook playbook.yaml, but you also need to have a proper structure to the playbook file. something like this:
---
- hosts: localhost
tasks:
- name: Create resource groupf
azure_rm_resourcegroup:
name: rg-cs-ansible
location: eastus

How to pass Azure service principal details to Ansible via command-line?

I am able to connect to Azure using Ansible by putting my service principle details into the credentials file stored in ~/.azure/credentials
That was OK for development, now (in production) I want to move away from using the text credentials file and pass the credentials to Ansible via the command-line via parameters.
How should this be done?
Any help is appreciated - thanks
I have tried:
ansible-playbook -i ./dev-env/epazure_rm.yml ./dev-env/site.yml -vvvv -u adminuser --extra-vars "AZURE_SUBSCRIPTION_ID=XXX AZURE_CLIENT_ID=XXX AZURE_SECRET=XXX AZURE_TENANT=XXX"
My Azure Dynamic Inventory plugin file looks like this
---
plugin: azure_rm
include_vm_resource_groups:
- rg-devdonal-eastus01
auth_source: auto
subscription_id: "{{ AZURE_SUBSCRIPTION_ID }}"
client_id: "{{ AZURE_CLIENT_ID }}"
secret: "{{ AZURE_SECRET }}"
tenant: "{{ AZURE_TENANT }}"
keyed_groups:
- prefix: tag
key: tags
You can use the environment variables for the credential and then read the variables from the environment, here is the example:
- debug: msg="{{ lookup('env','HOME') }} is an environment variable"
And there is also another issue shows the example.

Resources