ansible / terraform-provider-ansible

community terraform provider for ansible
https://registry.terraform.io/providers/ansible/ansible/latest
GNU General Public License v3.0
195 stars 43 forks source link

Ansible provider plugin issue #32

Open PratikMeneu opened 1 year ago

PratikMeneu commented 1 year ago

image

gravesm commented 1 year ago

Could you please provide more information about what the problem is you're having and what the terraform config you are using is?

PratikMeneu commented 1 year ago

Hi @gravesm , The issue i am facing is in two parts related to ansible-provider and ansible_playbook terraform resource

[ part 1] - when i specify the attribute [ ignore_playbook_failure = true ] in the ansible_playbook resource , the terraform apply stage runs successfully to it's completion givin success message, but the issue is that while inspecting the state file, the playbook task is failing giving error such as "Host UNREACHABLE" "ERROR: apache2.yml" file not found

image

-------> here is the output from state file for resource type = "ansible_playbook"

"ansible_playbook_stdout": "ansible-playbook [core 2.14.4]\n config file = /etc/ansible/ansible.cfg\n configured module search path = ['/home/pratik-001/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']\n ansible python module location = /home/pratik-001/.local/lib/python3.10/site-packages/ansible\n ansible collection location = /home/pratik-001/.ansible/collections:/usr/share/ansible/collections\n executable location = /home/pratik-001/.local/bin/ansible-playbook\n python version = 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] (/usr/bin/python3)\n jinja version = 3.1.2\n libyaml = True\nUsing /etc/ansible/ansible.cfg as config file\nSkipping callback 'default', as we already have a stdout callback.\nSkipping callback 'minimal', as we already have a stdout callback.\nSkipping callback 'oneline', as we already have a stdout callback.\n\nPLAYBOOK: apache2.yml **\n1 plays in ./apache2.yml\n\nPLAY [webserver] ***\n\nTASK [Gathering Facts] *\ntask path: /home/pratik-001/DevOps/Ansible/azterraform/apache2.yml:2\nfatal: [20.253.140.246]: UNREACHABLE! =\u003e {\"changed\": false, \"msg\": \"Failed to connect to the host via ssh: ssh: connect to host 20.253.140.246 port 22: Connection timed out\", \"unreachable\": true}\n\nPLAY RECAP *****\n20.253.140.246 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0 \n\n",

[ part 2 ] - when i specify the attribute [ ignore_playbook_failure = false ] in the ansible_playbook resource , the terraform apply stage fails giving the bellow mentioned error .

image

PratikMeneu commented 1 year ago

@gravesm Here is The minimal configuration you asked for:-

1] main.tf resource "azurerm_resource_group" "example" { name = "example-resources1" location = "West US" }

resource "azurerm_virtual_network" "example_vnet" { name = "example-network" address_space = ["10.0.0.0/16"] location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name }

resource "azurerm_subnet" "example_subnet" { name = "internal" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example_vnet.name address_prefixes = ["10.0.2.0/24"] }

resource "azurerm_public_ip" "example_pip" { name = "TestPublicIp2" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location allocation_method = "Dynamic" }

resource "azurerm_network_interface" "example_nic" { name = "example-nic" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name

ip_configuration { name = "internal" subnet_id = azurerm_subnet.example_subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.example_pip.id } }

resource "azurerm_network_interface_security_group_association" "exampl_nic_nsg_asso_inbound" { network_interface_id = azurerm_network_interface.example_nic.id network_security_group_id = azurerm_network_security_group.inbound_example.id }

resource "azurerm_network_security_group" "inbound_example" { name = "ansibleTestSecurityGroup1" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name

security_rule { name = "test123" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "22" destination_port_range = "22" source_address_prefix = "" destination_address_prefix = "" }

tags = { environment = "Production" } }

resource "azurerm_network_security_rule" "example" { name = "test456" priority = 100 direction = "Outbound" access = "Allow" protocol = "Tcp" source_port_range = "" destination_port_range = "" source_address_prefix = "" destination_address_prefix = "" resource_group_name = azurerm_resource_group.example.name network_security_group_name = azurerm_network_security_group.inbound_example.name }

resource "azurerm_linux_virtual_machine" "example" { name = "example-machine-7" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location size = "Standard_DS1_v2" admin_username = "pratik-001" network_interface_ids = [ azurerm_network_interface.example_nic.id, ]

admin_ssh_key { username = "pratik-001" public_key = file("~/.ssh/id_rsa.pub") }

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

source_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } }

resource "ansible_vault" "secrets" { vault_file = "./vault.yaml" vault_password_file = "./password" }

locals { decoded_vault_yaml = yamldecode(ansible_vault.secrets.yaml) }

resource "ansible_host" "my_ec2" {
name = azurerm_linux_virtual_machine.example.public_ip_address groups = ["webserver"]
variables = {
ansible_connection = "ssh", ansible_port = "22", ansible_user = "pratik-001", ansible_ssh_private_key_file = "~/.ssh/id_rsa", ansible_python_interpreter = "/usr/bin/python3", yaml_secret = local.decoded_vault_yaml.sensitive } }

resource "ansible_playbook" "playbook" { playbook = "./apache2.yml"
name = azurerm_linux_virtual_machine.example.public_ip_address replayable = true groups = ["webserver"] ignore_playbook_failure = false verbosity = 2 extra_vars = { ansible_connection = "ssh" } }

2] provider.tf

terraform { required_providers { aws = { source = "hashicorp/aws" version = "4.67.0" }

azurerm = {
  source  = "hashicorp/azurerm"
  version = "3.57.0"
}

ansible = {
  version = "~> 1.1.0"
  source  = "ansible/ansible"
}

} }

provider "aws" { region = "us-east-1" }

provider "azurerm" { features {} }

provider "ansible" {}

3] inventory.yml

plugin: cloud.terraform.terraform_provider

4] playbook = apache2.yml

Please ignore the ansible_vault resource in main.tf

PratikMeneu commented 1 year ago

Hi @gravesm, Did you get a chance to look at the issue, Please let me know your thoughts and the possible solutions . Thanks!!

vashistaankit commented 1 year ago

Hey @gravesm , will you be able to help us on this issue. It has impacting our current deliverables.
Thanks in advance.

gravesm commented 1 year ago

You don't need the provider.tf or inventory.yml file since you are using the ansible_playbook resource. But the error you are getting is coming from ansible and indicates that it can't connect to the host: Failed to connect to the host via ssh: ssh: connect to host 20.253.140.246 port 22: Connection timed out. This is most likely a configuration problem with your infrastructure.

vashistaankit commented 1 year ago

@gravesm We are trying to utilize this new provider https://registry.terraform.io/providers/ansible/ansible/latest/docs and as per the example provided there we have done this setup. We are able to execute this playbook normally if we use normal ansible commands to execute the playbook but when we integrate it with terraform using this we are facing this issue. Can you please look into this from that angle. Thanks!

kgopi05 commented 1 year ago

Im able execute my playbook using ansible successfully. But when i trying execute using Terraform ansible_playbook. i got the below error. Not sure where plugin logs saved . any help is much appreciated.

main.yaml

---
- name: to install nginx 
  hosts: all
  become: true 
  tasks:
  - name: install nginx
    ansible.builtin.apt:
     name: nginx
     state: present
playbook.tf

resource "ansible_host" "lab01" {
  name = "lab01.xxxx.com"
}

resource "ansible_playbook" "playbook" {
  playbook   = "main.yaml"
  name       = ansible_host.lab01.name
  replayable = true
}
│ Error: Plugin did not respond
│ 
│   with ansible_playbook.playbook,
│   on playbook.tf line 5, in resource "ansible_playbook" "playbook":
│    5: resource "ansible_playbook" "playbook" {
│ 
│ The plugin encountered an error, and failed to respond to the plugin.(*GRPCProvider).ApplyResourceChange
│ call. The plugin logs may contain more details.
derscheef commented 1 year ago

I am having the exact same issue. Did anyone find a solution to this ? Thanks in advance :)