Terraform 0.11 - Detecting Drift

बहाव का पता लगाना




terraform

बहाव का पता लगाना

बुनियादी ढांचे की मुख्य चुनौतियों में से एक कोड के रूप में सभी तैनात बुनियादी ढाँचे और उनकी संपत्तियों के रिकॉर्ड को अद्यतन रखा जा रहा है। टेराफॉर्म राज्य फाइल को राज्य सूचना बनाए रखने का प्रबंधन करता है, जिसे स्टेट फाइल कहा जाता है।

Terraform बुनियादी ढांचे के संसाधनों को परिभाषित करने के लिए घोषणात्मक कॉन्फ़िगरेशन फ़ाइलों का उपयोग करता है। यह कॉन्फ़िगरेशन बैकएंड एपीआई पर मौजूद सत्य के लक्ष्य स्रोत के रूप में कार्य करता है। टेराफॉर्म के बाहर इन्फ्रास्ट्रक्चर में परिवर्तन को टेराफॉर्म द्वारा विचलन के रूप में पता लगाया जाएगा और terraform plan भविष्य के रनों में एक अंतर के रूप में दिखाया गया है। इस प्रकार के परिवर्तन को "बहाव" के रूप में संदर्भित किया जाता है, और उपयोगकर्ताओं को उनके बुनियादी ढांचे में परिवर्तन की सूचना देने के लिए टेराफॉर्म की एक महत्वपूर्ण जिम्मेदारी है। यहां डेवलपर्स के लिए कुछ तकनीकों को सुनिश्चित किया गया है ताकि बहाव का पता लगाया जा सके

READ में सभी राज्य पर कब्जा

एक प्रदाता की READ विधि वह जगह है जहां राज्य को दूरस्थ एपीआई से टेराफ़ॉर्म राज्य तक सिंक्रनाइज़ किया जाता है। यह आवश्यक है कि स्कीमा में परिभाषित सभी विशेषताओं को रिकॉर्ड किया गया है और राज्य में अद्यतित रखा गया है। इस प्रदाता कोड पर विचार करें:

// resource_example_simple.go
package example

func resourceExampleSimple() *schema.Resource {
    return &schema.Resource{
        Read:   resourceExampleSimpleRead,
        Create: resourceExampleSimpleCreate,
        Schema: map[string]*schema.Schema{
            "name": {
                Type:     schema.TypeString,
                Required: true,
                ForceNew: true,
            },
            "type": {
                Type:     schema.TypeString,
                Optional: true,
            },
        },
    }
}

func resourceExampleSimpleRead(d *schema.ResourceData, meta interface{}) error {
   client := meta.(*ProviderApi).client
   resource, _ := client.GetResource(d.Id())
   d.Set("name", resource.Name)
   d.Set("type", resource.Type)
   return nil
}

स्कीमा में परिभाषित के अनुसार, type विशेषता वैकल्पिक है, अब इस विन्यास पर विचार करें:

# config.tf
resource "simple" "ex" {
   name = "example"
}

भले ही type को कॉन्फ़िगरेशन से छोड़ा गया हो, लेकिन यह महत्वपूर्ण है कि हम इसे READ फ़ंक्शन में स्थिति में रिकॉर्ड करें, क्योंकि बैकएंड API इसे डिफ़ॉल्ट मान पर सेट कर सकता है। सभी राज्य पर कब्जा करने के महत्व को समझाने के लिए एक कॉन्फ़िगरेशन पर विचार करें जो वैकल्पिक मान को दूसरे संसाधन में बदलता है:

resource "simple" "ex" {
   name = "example"
}

resource "another" "ex" {
  name = "${simple.ex.type}"
}

संशोधन के बाद अद्यतन स्थिति

एक प्रदाता का CREATE और UPDATE कार्य दूरस्थ एपीआई पर संसाधन बनाएंगे या संशोधित करेंगे। एपीआई अनिर्दिष्ट विशेषताओं के लिए डिफ़ॉल्ट मान प्रदान करने जैसी चीजें कर सकते हैं (जैसा कि ऊपर दिए गए उदाहरण config / प्रदाता कोड में वर्णित है), या इनपुट को सामान्य करें (किसी स्ट्रिंग में सभी वर्णों को कम या ऊपरी आवरण)। अंतिम परिणाम एक बैकएंड एपीआई है जिसमें उन मानों के संशोधित संस्करण हैं जो स्थानीय रूप से टेराफॉर्म में हैं। एक संसाधन के निर्माण या अद्यतन के तुरंत बाद, टेराफॉर्म में एक बासी स्थिति होगी, जिसके परिणामस्वरूप बाद की plan पर एक विचलन का पता चलेगा या एस apply , क्योंकि टेराफॉर्म अपने राज्य को ताज़ा करता है और अंतर को समेटना चाहता है। इस वजह से, तुरंत सिंक्रनाइज़ करने और उस अंतर से बचने के लिए सभी संशोधनों के अंत में READ को कॉल करना मानक अभ्यास है।

func resourceExampleSimpleRead(d *schema.ResourceData, meta interface{}) error {
   client := meta.(*ProviderApi).client
   resource, _ := client.GetResource(d.Id())
   d.Set("name", resource.Name)
   d.Set("type", resource.Type)
   return nil
}

func resourceExampleSimpleCreate(d *schema.ResourceData, meta interface{}) error {
   client := meta.(*ProviderApi).client
   name := d.Get("name").(string)
   client.CreateResource(name)
   d.SetId(name)
   return resourceExampleSimpleRead(d, meta)
}

कुल प्रकार की जाँच में त्रुटि

टेराफॉर्म स्कीमा को आदिम प्रकार और कुल प्रकार का उपयोग करके परिभाषित किया गया है। पूर्ववर्ती उदाहरणों में आदिम प्रकार होते हैं जिन्हें त्रुटि जाँच की आवश्यकता नहीं होती है। दूसरी ओर एकत्रित प्रकार, schema.TypeList , schema.TypeSet , और schema.TypeMap , राज्य में सेट होने पर कुंजी / मान युग्म में परिवर्तित हो जाते हैं। परिणामस्वरूप Set विधि में त्रुटि की जाँच होनी चाहिए, अन्यथा टेराफ़ॉर्म को लगता है कि टूटी हुई अवस्था होने के बावजूद यह ऑपरेशन सफल था। एपीआई प्रतिक्रियाओं की जांच करने में त्रुटि के लिए भी यही कहा जा सकता है।

# config.tf
resource "simple" "ex" {
   name = "example"
   type = "simple"
   tags = {
      name = "example"
   }
}
// resource_example_simple.go
package example

func resourceExampleSimple() *schema.Resource {
    return &schema.Resource{
        Read:   resourceExampleSimpleRead,
        Create: resourceExampleSimpleCreate,
        Schema: map[string]*schema.Schema{
            "name": {
                Type:     schema.TypeString,
                Required: true,
                ForceNew: true,
            },
            "type": {
                Type:     schema.TypeString,
                Optional: true,
            },
            "tags": {
                Type:     schema.TypeMap,
                Optional: true,
            },
        },
    }
}

func resourceExampleSimpleRead(d *schema.ResourceData, meta interface{}) error {
   client := meta.(*ProviderApi).client
   resource, err := client.GetResource(d.Id())
   if err != nil {
      return fmt.Errorf("error getting resource %s: %s", d.Id(), err)
   }
   d.Set("name", resource.Name)
   d.Set("type", resource.Type)
   if err := d.Set("tags", resource.TagMap); err != nil {
      return fmt.Errorf("error setting tags for resource %s: %s", d.Id(), err)
   }
   return nil
}

स्कीमा हेल्पर विधियों का उपयोग करें

जैसा कि उल्लेख किया गया है, रिमोट एपीआई अक्सर टेराफॉर्म के नियंत्रण के बाहर एक संसाधन की विशेषताओं के लिए म्यूटेशन कर सकते हैं। सामान्य उदाहरणों में डेटा शामिल हैं जिनमें अपरकेस अक्षर होते हैं और निचले स्तर के लिए सामान्यीकृत होते हैं, या जटिल विशेषताओं के लिए जटिल चूक निर्धारित की जाती हैं। इन स्थितियों के परिणामस्वरूप बहाव होता है, लेकिन टेराफॉर्म के स्कीमा फ़ंक्शन , जैसे कि DiffSuppressFunc या DiffSuppressFunc का उपयोग करके इसे DiffSuppressFunc जा सकता है।