Compile Terraform Provider ใช้เอง

เจอ bug ใน Terraform Provider ตัวที่ชื่อว่า ansible/ansible แต่อยากใช้งาน ก็เลยต้อง compile ใช้เองชั่วคราว

author image
drs

Technology evangelistic advocacy

Posted on 2023-12-23 00:51:47 +0700

ความเดิม

ผมเจอว่า Ansible Provider v1.1.0 มี bug และผ่านมาแล้ว 7 เดือน version ใหม่ก็ยังไม่ออกมา ทั้ง ๆ ที่เจอว่า source code ใน repository ... ด้วยความที่อยากใช้งาน ก็เลยหาทาง compile เพื่อใช้งานเอง โดยหลักการ ก็จะประมาณนี้ครับ

  1. clone source code มาจาก repository และทำการ compile ตามเอกสารของแต่ละ provider
  2. ทำ binary ไปวางไว้ที่ directory ตามรูปแบบที่ Terraform กำหนดไว้
    • File: terraform-provider-{NAME}_{VERSION}
    • Directory: $HOME/.terraform.d/plugins/{CUSTOM PATH}/{VERSION}/{OS}_{ARCH}/
  3. กำหนดค่าใน Terraform Configuration ให้อ่าน Terraform Provider จาก local แทนที่จะไป downlad จาก registry.terraform.io

ลุย !!!

  • Clone source code มาจาก repository
  • > git clone https://github.com/ansible/terraform-provider-ansible
    Cloning into 'terraform-provider-ansible'...
    remote: Enumerating objects: 562, done.
    remote: Counting objects: 100% (257/257), done.
    remote: Compressing objects: 100% (128/128), done.
    remote: Total 562 (delta 169), reused 158 (delta 122), pack-reused 305
    Receiving objects: 100% (562/562), 218.34 KiB | 2.14 MiB/s, done.
    Resolving deltas: 100% (299/299), done.
    
  • ทำการ compile Terraform provider และผลของการ compile จะได้ binary ชื่อว่า terraform-provider-ansible
  • > cd terraform-provider-ansible
    
    > make
    go build -o terraform-provider-ansible
    go: downloading github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0
    go: downloading github.com/hashicorp/terraform-plugin-go v0.19.0
    go: downloading github.com/hashicorp/go-plugin v1.5.1
    go: downloading github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
    go: downloading github.com/hashicorp/terraform-plugin-log v0.9.0
    go: downloading google.golang.org/grpc v1.59.0
    go: downloading github.com/vmihailenco/msgpack v4.0.4+incompatible
    go: downloading golang.org/x/sys v0.14.0
    go: downloading github.com/hashicorp/terraform-registry-address v0.2.2
    go: downloading google.golang.org/protobuf v1.31.0
    go: downloading golang.org/x/text v0.14.0
    go: downloading github.com/hashicorp/hcl/v2 v2.18.0
    go: downloading github.com/zclconf/go-cty v1.14.0
    go: downloading golang.org/x/net v0.18.0
    go: downloading google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17
    go: downloading github.com/hashicorp/terraform-svchost v0.1.1
    go: downloading github.com/apparentlymart/go-textseg/v15 v15.0.0
    
    > ls -la terraform-provider-ansible
    -rwxr-xr-x@ 1 drs  staff  20689266 Dec 23 13:55 terraform-provider-ansible
    
  • สำหรับเครื่องที่ใช้ทดสอบ เป๋ยเครื่อง Macbook Air M2 และผมตั้งใจตั้ง version ให้ต่างไปจาก official version ก็เลยกำหนดให้เป็น v99.99.0 ดังนั้น ค่าต่าง ๆ ในการกำหนดชื่อไฟล์ และ directory ก็จะเป็นค่าดังนี้
    • NAME: ansible
    • VERSION: 99.99.0
    • CUSTOM PATH: local/ansible/ansible
    • OS: darwin
    • ARCH: arm64
  • Directory: $HOME/.terraform.d/plugins/{CUSTOM PATH}/{VERSION}/{OS}_{ARCH}/
    > mkdir -p $HOME/.terraform.d/plugins/local/ansible/ansible/99.99.0/darwin_arm64
    
    File: terraform-provider-{NAME}_{VERSION}
    > cp terraform-provider-ansible $HOME/.terraform.d/plugins/local/ansible/ansible/99.99.0/darwin_arm64/terraform-provider-ansible_99.99.0
    > cd ..
    

ทดสอบใช้งาน

  1. ใน Terraform Configuration มีการเรียกใช้งาน provider 2 ตัวคือ DigitalOcean และ Ansible เพื่อทดสองสร้าง ​Droplet (Virtual Machine) ใน DigitalOcean และเรียกใช้งาน Ansible Playbook หลังจากที่สร้าง Droplet เสร็จ
    ข้อสังเกตุในการอ้างถึง Ansible Provider จะอยู่ใน block terraform {} ในส่วนที่ชื่อว่า source และ version

  2. terraform {
      required_providers {
        ansible = {
          source = "local/ansible/ansible"
          version = "99.99.0"
        }
        digitalocean = {
          source = "digitalocean/digitalocean"
        }
      }
    }
    
    data "digitalocean_ssh_key" "terraform" {
      name = "MyED25519"
    }
    variable "pvt_key" {
      type = string
      description = "SSH Private Key"
      default = "~/.ssh/id_ed25519"
    }
    
    resource "digitalocean_droplet" "web" {
      image  = "ubuntu-22-04-x64"
      name   = "web0"
      region = "sgp1"
      size   = "s-1vcpu-1gb"
      ssh_keys = [
        data.digitalocean_ssh_key.terraform.id
      ]
      provisioner "remote-exec" {
        connection {
          host = self.ipv4_address
          user = "root"
          type = "ssh"
          private_key = file(var.pvt_key)
          timeout = "2m"
        }
        inline = [
         "hostname",
        ]
      }
    }
    resource "ansible_playbook" "playbook" {
      playbook   = "myplaybook.yaml"
      name       = digitalocean_droplet.web.ipv4_address
    }
    
  3. เรียกใช้่งาน terraform
  4.  > terraform init
    
    Initializing the backend...
    
    Initializing provider plugins...
    - Finding latest version of digitalocean/digitalocean...
    - Finding local/ansible/ansible versions matching "99.99.0"...
    - Installing digitalocean/digitalocean v2.34.1...
    - Installed digitalocean/digitalocean v2.34.1 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)
    - Installing local/ansible/ansible v99.99.0...
    - Installed local/ansible/ansible v99.99.0 (unauthenticated)
    
    [... truncated output ...]
    
    > terraform apply --auto-approve
    data.digitalocean_ssh_key.terraform: Reading...
    data.digitalocean_ssh_key.terraform: Read complete after 1s [name=MyED25519]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      + create
    
    [... truncated output ...]
    
    ansible_playbook.playbook: Creating...
    ansible_playbook.playbook: Creation complete after 4s [id=2023-12-24 00:36:35.017913 +0700 +07 m=+83.651249334]
    
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    

ผมทดสอบจำลองสถานการณ์ที่ทำให้เกิดปัญหา เมื่อใช้งาน Ansible Provider v1.1.0 ไม่พบปัญหาการใช้งาน เห็นได้ว่า Ansible Provider ที่ compile จาก source code ใน github สามารถทำงานได้อย่างถูกต้อง


Reference:



cover

Share on

Tags

Human knowledge belongs to the world

a line from the movie "Antitrust"