CINXE.COM
Developing Terraform Custom Provider for Terraform v0.12 - DEV Community
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Developing Terraform Custom Provider for Terraform v0.12 - DEV Community</title> <meta name="last-updated" content="2025-02-17 15:53:32 UTC"> <meta name="user-signed-in" content="false"> <meta name="head-cached-at" content="1739807612"> <meta name="environment" content="production"> <link rel="stylesheet" href="https://assets.dev.to/assets/minimal-0a971eb021d2dc2b145c1df786e1b97f418c6b2d066e79802fea980acb513937.css" media="all" id="main-minimal-stylesheet" /> <link rel="stylesheet" href="https://assets.dev.to/assets/views-1c703342dce6eac414f19ca7fd07bcf83cbe44088659758144e52e7fa1e92dd3.css" media="all" id="main-views-stylesheet" /> <link rel="stylesheet" href="https://assets.dev.to/assets/crayons-0f2fc85bc159498f8ae6fba58c460e6deba863d02d59dfa994c1954976ddb6cc.css" media="all" id="main-crayons-stylesheet" /> <script src="https://assets.dev.to/assets/base-a87669a7c932717e71153a0e9be51887fd49f60281c77873f33571fab239e9d6.js" defer="defer"></script> <script src="https://assets.dev.to/assets/application-7258612fccf5d56314a6e4ad1898b4f818f474c4bb3485e302428d489a769a17.js" defer="defer"></script> <script src="https://assets.dev.to/assets/baseInitializers-ee70590bbbe9b8f9d750ea9b4b7e809c47123e9064196238ba4e65bc65caf708.js" defer="defer"></script> <script src="https://assets.dev.to/assets/baseTracking-b6bf73e5ee66633e151e7d5b7c6bbccedfa4c59e3615be97b98c4c0f543ddae7.js" defer="defer"></script> <meta name="search-script" content="https://assets.dev.to/assets/Search-1667defd820799649d6c3b2864f13786058190df703dd50ab75dce1ccb834c4b.js"> <link rel="canonical" href="https://dev.to/chefgs/developing-terraform-custom-provider-49f2" /> <meta name="description" content="Table of Content Introduction Bit of intro into Terraform Terraform Provider Terraform... Tagged with terraform, tutorial, showdev."> <meta name="keywords" content="terraform, tutorial, showdev, software, coding, development, engineering, inclusive, community"> <meta property="og:type" content="article" /> <meta property="og:url" content="https://dev.to/chefgs/developing-terraform-custom-provider-49f2" /> <meta property="og:title" content="Developing Terraform Custom Provider for Terraform v0.12" /> <meta property="og:description" content="Table of Content Introduction Bit of intro into Terraform Terraform Provider Terraform..." /> <meta property="og:site_name" content="DEV Community" /> <meta name="twitter:site" content="@thepracticaldev"> <meta name="twitter:creator" content="@saransid"> <meta name="twitter:title" content="Developing Terraform Custom Provider for Terraform v0.12"> <meta name="twitter:description" content="Table of Content Introduction Bit of intro into Terraform Terraform Provider Terraform..."> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:widgets:new-embed-design" content="on"> <meta name="robots" content="max-snippet:-1, max-image-preview:large, max-video-preview:-1"> <meta property="og:image" content="https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png" /> <meta name="twitter:image:src" content="https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png"> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> <link rel="icon" type="image/x-icon" href="https://media2.dev.to/dynamic/image/width=32,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" /> <link rel="apple-touch-icon" href="https://media2.dev.to/dynamic/image/width=180,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"> <link rel="apple-touch-icon" sizes="152x152" href="https://media2.dev.to/dynamic/image/width=152,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"> <link rel="apple-touch-icon" sizes="180x180" href="https://media2.dev.to/dynamic/image/width=180,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"> <link rel="apple-touch-icon" sizes="167x167" href="https://media2.dev.to/dynamic/image/width=167,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"> <link href="https://media2.dev.to/dynamic/image/width=192,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" rel="icon" sizes="192x192" /> <link href="https://media2.dev.to/dynamic/image/width=128,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" rel="icon" sizes="128x128" /> <meta name="apple-mobile-web-app-title" content="dev.to"> <meta name="application-name" content="dev.to"> <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"> <meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)"> <link rel="search" href="https://dev.to/open-search.xml" type="application/opensearchdescription+xml" title="DEV Community" /> <meta property="forem:name" content="DEV Community" /> <meta property="forem:logo" content="https://media2.dev.to/dynamic/image/width=512,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" /> <meta property="forem:domain" content="dev.to" /> </head> <body class="sans-serif-article-body default-header" data-user-status="logged-out" data-community-name="DEV Community" data-subscription-icon="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png" data-locale="en" data-honeybadger-key="hbp_nqu4Y66HuEKlD6YRGssZuRQnPOjDm50J8Zkr" data-deployed-at="2025-02-14T17:48:00Z" data-latest-commit-id="6eae977a3ad3ef9e73c77442f1aca852fd05f095" data-ga-tracking="UA-71991109-1" data-cookie-banner-user-context="logged_out_only" data-cookie-banner-platform-context="off" data-algolia-id="PRSOBFP46H" data-algolia-search-key="9aa7d31610cba78851c9b1f63776a9dd" data-algolia-display="true" data-dynamic-url-component="bb-2" data-ga4-tracking-id="G-TYEM8Y3JN3"> <script> if (navigator.userAgent.includes('ForemWebView/1') || window.frameElement) { document.body.classList.add("hidden-shell"); } </script> <link rel="stylesheet" href="https://assets.dev.to/assets/minimal-0a971eb021d2dc2b145c1df786e1b97f418c6b2d066e79802fea980acb513937.css" media="all" id="secondary-minimal-stylesheet" /> <link rel="stylesheet" href="https://assets.dev.to/assets/views-1c703342dce6eac414f19ca7fd07bcf83cbe44088659758144e52e7fa1e92dd3.css" media="all" id="secondary-views-stylesheet" /> <link rel="stylesheet" href="https://assets.dev.to/assets/crayons-0f2fc85bc159498f8ae6fba58c460e6deba863d02d59dfa994c1954976ddb6cc.css" media="all" id="secondary-crayons-stylesheet" /> <div id="body-styles"> <style> :root { --accent-brand-lighter-rgb: 80, 99, 301; --accent-brand-rgb: 59, 73, 223; --accent-brand-darker-rgb: 47, 58, 178; } </style> </div> <div id="audiocontent" data-podcast=""> </div> <div class="navigation-progress" id="navigation-progress"></div> <header id="topbar" class="crayons-header topbar print-hidden"> <span id="route-change-target" tabindex="-1"></span> <a href="#main-content" class="skip-content-link">Skip to content</a> <div class="crayons-header__container"> <span class="inline-block m:hidden "> <button class="c-btn c-btn--icon-alone js-hamburger-trigger mx-2"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="annd6iagntkap2gm0qxjq6g8uhn7i69v" class="crayons-icon"><title id="annd6iagntkap2gm0qxjq6g8uhn7i69v">Navigation menu</title> <path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"></path> </svg> </button> </span> <a href="/" class="site-logo" aria-label="DEV Community Home"> <img class="site-logo__img" src="https://media2.dev.to/dynamic/image/quality=100/https://dev-to-uploads.s3.amazonaws.com/uploads/logos/resized_logo_UQww2soKuUsjaOGNB38o.png" style="aspect-ratio: 10 / 8" alt="DEV Community"> </a> <div class="crayons-header--search js-search-form" id="header-search"> <form accept-charset="UTF-8" method="get" action="/search" role="search"> <div class="crayons-fields crayons-fields--horizontal"> <div class="crayons-field flex-1 relative"> <input id="search-input" class="crayons-header--search-input crayons-textfield js-search-input" type="text" id="nav-search" name="q" placeholder="Find related posts..." autocomplete="off" /> <button type="submit" aria-label="Search" class="c-btn c-btn--icon-alone absolute inset-px right-auto mt-0 py-0"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="ajins6ogbl3xxmhj6rnrm8qlge314am1" aria-hidden="true" class="crayons-icon"><title id="ajins6ogbl3xxmhj6rnrm8qlge314am1">Search</title> <path d="M18.031 16.617l4.283 4.282-1.415 1.415-4.282-4.283A8.96 8.96 0 0111 20c-4.968 0-9-4.032-9-9s4.032-9 9-9 9 4.032 9 9a8.96 8.96 0 01-1.969 5.617zm-2.006-.742A6.977 6.977 0 0018 11c0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7a6.977 6.977 0 004.875-1.975l.15-.15z"></path> </svg> </button> <a class="crayons-header--search-brand-indicator" href="https://www.algolia.com/developers/?utm_source=devto&utm_medium=referral" target="_blank" rel="noopener noreferrer"> Powered by <svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" width="24" height="24" viewBox="0 0 500 500.34" role="img" aria-labelledby="a80i2midzvd9wl68tzw7wilsh521nmxn" aria-hidden="true" class="crayons-icon"><title id="a80i2midzvd9wl68tzw7wilsh521nmxn">Search</title> <defs></defs><path class="cls-1" d="M250,0C113.38,0,2,110.16,.03,246.32c-2,138.29,110.19,252.87,248.49,253.67,42.71,.25,83.85-10.2,120.38-30.05,3.56-1.93,4.11-6.83,1.08-9.52l-23.39-20.74c-4.75-4.22-11.52-5.41-17.37-2.92-25.5,10.85-53.21,16.39-81.76,16.04-111.75-1.37-202.04-94.35-200.26-206.1,1.76-110.33,92.06-199.55,202.8-199.55h202.83V407.68l-115.08-102.25c-3.72-3.31-9.43-2.66-12.43,1.31-18.47,24.46-48.56,39.67-81.98,37.36-46.36-3.2-83.92-40.52-87.4-86.86-4.15-55.28,39.65-101.58,94.07-101.58,49.21,0,89.74,37.88,93.97,86.01,.38,4.28,2.31,8.28,5.53,11.13l29.97,26.57c3.4,3.01,8.8,1.17,9.63-3.3,2.16-11.55,2.92-23.6,2.07-35.95-4.83-70.39-61.84-127.01-132.26-131.35-80.73-4.98-148.23,58.18-150.37,137.35-2.09,77.15,61.12,143.66,138.28,145.36,32.21,.71,62.07-9.42,86.2-26.97l150.36,133.29c6.45,5.71,16.62,1.14,16.62-7.48V9.49C500,4.25,495.75,0,490.51,0H250Z"></path> </svg> Algolia </a> </div> </div> </form> </div> <div class="flex items-center h-100 ml-auto"> <div class="flex" id="authentication-top-nav-actions"> <span class="hidden m:block"> <a href="https://dev.to/enter" class="c-link c-link--block mr-2 whitespace-nowrap ml-auto" data-no-instant> Log in </a> </span> <a href="https://dev.to/enter?state=new-user" data-tracking-id="ca_top_nav" data-tracking-source="top_navbar" class="c-cta c-cta--branded whitespace-nowrap mr-2" data-no-instant> Create account </a> </div> </div> </div> </header> <div class="hamburger"> <div class="hamburger__content"> <header class="hamburger__content__header"> <h2 class="fs-l fw-bold flex-1 break-word lh-tight">DEV Community</h2> <button class="c-btn c-btn--icon-alone js-hamburger-trigger shrink-0" aria-label="Close"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="ajnr94d5vf7oau17431noo9asa7abl1b" aria-hidden="true" class="crayons-icon c-btn__icon"><title id="ajnr94d5vf7oau17431noo9asa7abl1b">Close</title><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636l4.95 4.95z"></path></svg> </button> </header> <div class="p-2 js-navigation-links-container" id="authentication-hamburger-actions"> </div> </div> <div class="hamburger__overlay js-hamburger-trigger"></div> </div> <div id="active-broadcast" class="broadcast-wrapper"></div> <div id="page-content" class="wrapper stories stories-show articletag-terraform articletag-tutorial articletag-showdev articleuser-303053" data-current-page="stories-show"> <div id="page-content-inner" data-internal-nav="false"> <div id="page-route-change" class="screen-reader-only" aria-live="polite" aria-atomic="true"></div> <link rel="prefetch" href="/reactions?article_id=502724"> <style> .html-variant-wrapper { display: none} </style> <script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.2.10/webcomponents-loader.js" integrity="sha384-3HK5hxQbkFqOIxMbpROlRmRtYl2LBZ52t+tqcjzsmr9NJuOWQxl8RgQSyFvq2lhy" crossorigin="anonymous" defer></script> <script src="https://assets.dev.to/assets/webShare-0686f0b9ac40589694ef6ae6a6202c44119bc781c254f6cf6d52d8a008461156.js" defer="defer"></script> <script src="https://assets.dev.to/assets/articlePage-e91bed0487621b06608474cfabffa186165e1f43f05b24581203ccc21e7aa45d.js" defer="defer"></script> <script src="https://assets.dev.to/assets/commentDropdowns-7a28d130e5b78d38b30a9495a964003a66bd64fa455fc70b766d69cf06b9ba24.js" defer="defer"></script> <script type="application/ld+json"> {"@context":"http://schema.org","@type":"Article","mainEntityOfPage":{"@type":"WebPage","@id":"https://dev.to/chefgs/developing-terraform-custom-provider-49f2"},"url":"https://dev.to/chefgs/developing-terraform-custom-provider-49f2","image":["https://media2.dev.to/dynamic/image/width=1080,height=1080,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png","https://media2.dev.to/dynamic/image/width=1280,height=720,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png","https://media2.dev.to/dynamic/image/width=1600,height=900,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png"],"publisher":{"@context":"http://schema.org","@type":"Organization","name":"DEV Community","logo":{"@context":"http://schema.org","@type":"ImageObject","url":"https://media2.dev.to/dynamic/image/width=192,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png","width":"192","height":"192"}},"headline":"Developing Terraform Custom Provider for Terraform v0.12","author":{"@context":"http://schema.org","@type":"Person","url":"https://dev.to/chefgs","name":"Saravanan Gnanaguru"},"datePublished":"2020-10-31T19:00:30Z","dateModified":"2022-10-05T13:30:49Z"} </script> <div class="crayons-layout crayons-layout--3-cols crayons-layout--article"> <aside class="crayons-layout__sidebar-left" aria-label="Article actions"> <div class="crayons-article-actions print-hidden"> <div class="crayons-article-actions__inner"> <div class="reaction-drawer__outer hoverdown" style=""> <button id="reaction-drawer-trigger" aria-label="reaction-drawer-trigger" aria-pressed="false" class="hoverdown-trigger crayons-reaction pseudo-reaction crayons-tooltip__activator relative"> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction--like crayons-reaction__icon--inactive" style="width: 40px; height: 40px"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" role="img" aria-hidden="true" class="crayons-icon"> <g clip-path="url(#clip0_988_3276)"> <path d="M19 14V17H22V19H18.999L19 22H17L16.999 19H14V17H17V14H19ZM20.243 4.75698C22.505 7.02498 22.583 10.637 20.479 12.992L19.059 11.574C20.39 10.05 20.32 7.65998 18.827 6.16998C17.324 4.67098 14.907 4.60698 13.337 6.01698L12.002 7.21498L10.666 6.01798C9.09103 4.60598 6.67503 4.66798 5.17203 6.17198C3.68203 7.66198 3.60703 10.047 4.98003 11.623L13.412 20.069L12 21.485L3.52003 12.993C1.41603 10.637 1.49503 7.01898 3.75603 4.75698C6.02103 2.49298 9.64403 2.41698 12 4.52898C14.349 2.41998 17.979 2.48998 20.242 4.75698H20.243Z" fill="#525252"></path> </g> <defs> <clipPath id="clip0_988_3276"> <rect width="24" height="24" fill="white"></rect> </clipPath> </defs> </svg> </span> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--active" style="width: 40px; height: 40px"> <img aria_hidden="true" height="24" width="24" src="https://assets.dev.to/assets/heart-plus-active-9ea3b22f2bc311281db911d416166c5f430636e76b15cd5df6b3b841d830eefa.svg" /> </span> <span class="crayons-reaction__count" id="reaction_total_count"> <span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span> </span> <span class="crayons-tooltip__content"> Add reaction </span> </button> <div class="reaction-drawer" aria-expanded="false"> <div class="reaction-drawer__container"> <button id="reaction-butt-like" name="Like" aria-label="Like" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="like"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-like"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Like </span> </button> <button id="reaction-butt-unicorn" name="Unicorn" aria-label="Unicorn" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="unicorn"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-unicorn"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Unicorn </span> </button> <button id="reaction-butt-exploding_head" name="Exploding Head" aria-label="Exploding Head" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="exploding_head"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-exploding_head"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Exploding Head </span> </button> <button id="reaction-butt-raised_hands" name="Raised Hands" aria-label="Raised Hands" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="raised_hands"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-raised_hands"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Raised Hands </span> </button> <button id="reaction-butt-fire" name="Fire" aria-label="Fire" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="fire"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-fire"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Fire </span> </button> </div> </div> </div> <button id="reaction-butt-comment" aria-label="Jump to Comments" aria-pressed="false" class="crayons-reaction crayons-reaction--comment crayons-tooltip__activator relative" data-category="comment"> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-hidden="true" class="crayons-icon"> <path d="M10 3h4a8 8 0 010 16v3.5c-5-2-12-5-12-11.5a8 8 0 018-8zm2 14h2a6 6 0 000-12h-4a6 6 0 00-6 6c0 3.61 2.462 5.966 8 8.48V17z"></path> </svg> </span> <span class="crayons-reaction__count" id="reaction-number-comment" data-count="0"> <span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span> </span> <span data-testid="tooltip" class="crayons-tooltip__content"> Jump to Comments </span> </button> <button id="reaction-butt-readinglist" aria-label="Add to reading list" aria-pressed="false" class="crayons-reaction crayons-reaction--readinglist crayons-tooltip__activator relative" data-category="readinglist"> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-hidden="true" class="crayons-icon"> <path d="M5 2h14a1 1 0 011 1v19.143a.5.5 0 01-.766.424L12 18.03l-7.234 4.536A.5.5 0 014 22.143V3a1 1 0 011-1zm13 2H6v15.432l6-3.761 6 3.761V4z"></path> </svg> </span> <span class="crayons-reaction__count" id="reaction-number-readinglist"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Save </span> </button> <button id="reaction-butt-boost" aria-label="Boost" aria-pressed="false" class="crayons-reaction crayons-reaction--boost crayons-tooltip__activator relative"> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" role="img" aria-hidden="true" class="crayons-icon" width="24" height="24"> <path transform="translate(24,0) scale(-1,1)" d="M6 4H21C21.5523 4 22 4.44772 22 5V12H20V6H6V9L1 5L6 1V4ZM18 20H3C2.44772 20 2 19.5523 2 19V12H4V18H18V15L23 19L18 23V20Z"></path> </svg> </span> <span data-testid="tooltip" class="crayons-tooltip__content"> Boost </span> </button> <div class="only-sidebar-menu-item"> <div id="mod-actions-menu-btn-area" class="print-hidden trusted-visible-block align-center"> </div> </div> <div class="align-center m:relative"> <button id="article-show-more-button" aria-controls="article-show-more-dropdown" aria-expanded="false" aria-haspopup="true" class="dropbtn crayons-btn crayons-btn--ghost-dimmed crayons-btn--icon-rounded" aria-label="Share post options"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" aria-labelledby="ajiaog2gccwwvy44a41c27blssxd9xnq" aria-hidden="true" class="crayons-icon dropdown-icon"><title id="ajiaog2gccwwvy44a41c27blssxd9xnq">More...</title><path fill-rule="evenodd" clip-rule="evenodd" d="M7 12a2 2 0 11-4 0 2 2 0 014 0zm7 0a2 2 0 11-4 0 2 2 0 014 0zm5 2a2 2 0 100-4 2 2 0 000 4z"></path></svg> </button> <div id="article-show-more-dropdown" class="crayons-dropdown side-bar left-2 right-2 m:right-auto m:left-100 s:left-auto mb-1 m:mb-0 top-unset bottom-100 m:top-0 m:bottom-unset"> <div class="only-mobile-menu-item"> <button class="mod-actions-menu-btn crayons-link crayons-link--block w-100 bg-transparent border-0 fw-bold"> Moderate </button> </div> <div> <button id="copy-post-url-button" class="flex justify-between crayons-link crayons-link--block w-100 bg-transparent border-0" data-postUrl="https://dev.to/chefgs/developing-terraform-custom-provider-49f2"> <span class="fw-bold">Copy link</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="article-copy-icon" role="img" aria-labelledby="a15tpmvbj2j6qg3ipuq3huv48gyyv88l" aria-hidden="true" class="crayons-icon mx-2 shrink-0"><title id="a15tpmvbj2j6qg3ipuq3huv48gyyv88l">Copy link</title> <path d="M7 6V3a1 1 0 011-1h12a1 1 0 011 1v14a1 1 0 01-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 013 21l.003-14c0-.552.45-1 1.007-1H7zm2 0h8v10h2V4H9v2zm-2 5v2h6v-2H7zm0 4v2h6v-2H7z"></path> </svg> </button> <div id="article-copy-link-announcer" aria-live="polite" class="crayons-notice crayons-notice--success my-2 p-1" aria-live="polite" hidden>Copied to Clipboard</div> </div> <div class="Desktop-only"> <a target="_blank" class="crayons-link crayons-link--block" rel="noopener" href='https://twitter.com/intent/tweet?text=%22Developing%20Terraform%20Custom%20Provider%20for%20Terraform%20v0.12%22%20by%20%40saransid%20%23DEVCommunity%20https%3A%2F%2Fdev.to%2Fchefgs%2Fdeveloping-terraform-custom-provider-49f2'> Share to X </a> <a target="_blank" class="crayons-link crayons-link--block" rel="noopener" href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fdev.to%2Fchefgs%2Fdeveloping-terraform-custom-provider-49f2&title=Developing%20Terraform%20Custom%20Provider%20for%20Terraform%20v0.12&summary=Table%20of%20Content%20%20%20%20Introduction%20Bit%20of%20intro%20into%20Terraform%20Terraform%20Provider%20Terraform...&source=DEV%20Community"> Share to LinkedIn </a> <a target="_blank" class="crayons-link crayons-link--block" rel="noopener" href="https://www.facebook.com/sharer.php?u=https%3A%2F%2Fdev.to%2Fchefgs%2Fdeveloping-terraform-custom-provider-49f2"> Share to Facebook </a> <a target="_blank" class="crayons-link crayons-link--block" rel="noopener" href="https://toot.kytta.dev/?text=https%3A%2F%2Fdev.to%2Fchefgs%2Fdeveloping-terraform-custom-provider-49f2"> Share to Mastodon </a> </div> <web-share-wrapper shareurl="https://dev.to/chefgs/developing-terraform-custom-provider-49f2" sharetitle="Developing Terraform Custom Provider for Terraform v0.12" sharetext="Table of Content Introduction Bit of intro into Terraform Terraform Provider Terraform..." template="web-share-button"> </web-share-wrapper> <template id="web-share-button"> <a href="#" class="dropdown-link-row crayons-link crayons-link--block">Share Post via...</a> </template> <a href="/report-abuse" class="crayons-link crayons-link--block">Report Abuse</a> </div> </div> </div> </div> </aside> <main id="main-content" class="crayons-layout__content grid gap-4"> <div class="article-wrapper"> <article class="crayons-card crayons-article mb-4" id="article-show-container" data-article-id="502724" data-article-slug="developing-terraform-custom-provider-49f2" data-author-id="303053" data-author-name="Saravanan Gnanaguru" data-author-username="chefgs" data-co-author-ids="" data-path="/chefgs/developing-terraform-custom-provider-49f2" data-pin-path="/stories/feed/pinned_article" data-pinned-article-id="" data-published="true" data-scheduled="false" lang=en > <header class="crayons-article__header" id="main-title"> <a class="crayons-article__cover" href="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png"> <img src="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png" style="aspect-ratio: auto 1000 / 420;" width="1000" height="420" class="crayons-article__cover__image" alt="Cover image for Developing Terraform Custom Provider for Terraform v0.12"> </a> <div class="crayons-article__header__meta"> <div class="flex s:items-start flex-col s:flex-row"> <div id="action-space" class="crayons-article__actions mb-4 s:mb-0 s:order-last"></div> <div class="flex flex-1 mb-5 items-start"> <div class="relative"> <a href="/chefgs"><img class="radius-full align-middle" src="https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F303053%2Fd97f6bd8-5ba4-4e3d-a8ad-6efc603a645a.jpg" width="40" height="40" alt="Saravanan Gnanaguru" /></a> </div> <div class="pl-3 flex-1"> <a href="/chefgs" class="crayons-link fw-bold">Saravanan Gnanaguru</a> <p class="fs-xs color-base-60"> Posted on <time datetime="2020-10-31T19:00:30Z" class="date">Oct 31, 2020</time> • Edited on <time datetime="2022-10-05T13:30:49Z" class="date">Oct 5, 2022</time> </p> </div> </div> </div> <div class="multiple_reactions_engagement"> <span class="reaction_engagement_like hidden"> <img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24" /> <span id="reaction_engagement_like_count"> </span> </span> <span class="reaction_engagement_unicorn hidden"> <img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24" /> <span id="reaction_engagement_unicorn_count"> </span> </span> <span class="reaction_engagement_exploding_head hidden"> <img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24" /> <span id="reaction_engagement_exploding_head_count"> </span> </span> <span class="reaction_engagement_raised_hands hidden"> <img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="24" height="24" /> <span id="reaction_engagement_raised_hands_count"> </span> </span> <span class="reaction_engagement_fire hidden"> <img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24" /> <span id="reaction_engagement_fire_count"> </span> </span> </div> <h1 class=" fs-3xl m:fs-4xl l:fs-5xl fw-bold s:fw-heavy lh-tight mb-2 medium"> Developing Terraform Custom Provider for Terraform v0.12 </h1> <div class="spec__tags flex flex-wrap"> <a class="crayons-tag " style=" --tag-bg: rgba(59, 73, 223, 0.10); --tag-prefix: #3b49df; --tag-bg-hover: rgba(59, 73, 223, 0.10); --tag-prefix-hover: #3b49df; " href="/t/terraform"><span class="crayons-tag__prefix">#</span>terraform</a> <a class="crayons-tag " style=" --tag-bg: rgba(254, 255, 165, 0.10); --tag-prefix: #FEFFA5; --tag-bg-hover: rgba(254, 255, 165, 0.10); --tag-prefix-hover: #FEFFA5; " href="/t/tutorial"><span class="crayons-tag__prefix">#</span>tutorial</a> <a class="crayons-tag " style=" --tag-bg: rgba(9, 27, 71, 0.10); --tag-prefix: #091b47; --tag-bg-hover: rgba(9, 27, 71, 0.10); --tag-prefix-hover: #091b47; " href="/t/showdev"><span class="crayons-tag__prefix">#</span>showdev</a> </div> </div> </header> <div class="crayons-article__main "> <nav class="series-switcher crayons-card crayons-card--secondary"> <header class="crayons-card__header"> <h2 class="crayons-subtitle-2"> <a href="/chefgs/series/9495">Terraform Tutorials (8 Part Series)</a> </h2> </header> <div class="series-switcher__list"> <a href="/chefgs/developing-terraform-custom-provider-49f2" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--active " data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png" title="Published Oct 31 '20"> <span class="series-switcher__num">1</span> <span class="series-switcher__title">Developing Terraform Custom Provider for Terraform v0.12</span> </a> <a href="/chefgs/create-apache-web-server-in-aws-using-terraform-1fpj" class="crayons-link crayons-link--contentful series-switcher__link " data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0j1yvjylbe6jv53e7ta.png" title="Published Jun 19 '21"> <span class="series-switcher__num">2</span> <span class="series-switcher__title">Create Apache Web Server in AWS Using Terraform</span> </a> <a href="/chefgs/create-and-configure-google-cloud-instance-using-terraform-and-chef-3g01" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--inbetween" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fet46qubgi3xq6ylq3bk7.png" id="collection-link-inbetween" data-no-instant title="View more"> <span class="series-switcher__num">...</span> <span class="series-switcher__title">4 more parts...</span> </a> <a href="/chefgs/create-and-configure-google-cloud-instance-using-terraform-and-chef-3g01" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--hidden" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fet46qubgi3xq6ylq3bk7.png" title="Published Jul 15 '21"> <span class="series-switcher__num">3</span> <span class="series-switcher__title">Create and Configure Google Cloud Instance using Terraform and Chef</span> </a> <a href="/chefgs/developing-a-custom-provider-in-terraform-v013-49l8" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--hidden" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrxbfdsrqwgjx9yw8m6t.png" title="Published Nov 20 '21"> <span class="series-switcher__num">4</span> <span class="series-switcher__title">How to Develop a Custom Provider in Terraform v0.13+</span> </a> <a href="/aws-builders/create-aws-infrastructure-using-cdk-for-terraform-3eg5" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--hidden" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foj6x2ww0ogr0f2eg7lrk.png" title="Published Mar 24 '22"> <span class="series-switcher__num">5</span> <span class="series-switcher__title">Create AWS Infrastructure using CDK for Terraform</span> </a> <a href="/chefgs/deploy-kubernetes-resources-in-minikube-cluster-using-terraform-1p8o" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--hidden" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnr00jj26rkboeu26mp2j.png" title="Published Jun 25 '22"> <span class="series-switcher__num">6</span> <span class="series-switcher__title">Deploy Kubernetes Resources in Minikube cluster using Terraform</span> </a> <a href="/aws-builders/create-amazon-eks-cluster-using-terraform-module-27p5" class="crayons-link crayons-link--contentful series-switcher__link " data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jt1dguvt2q9axxl7w0d.jpeg" title="Published Apr 18 '23"> <span class="series-switcher__num">7</span> <span class="series-switcher__title">Create Amazon EKS Cluster using Terraform Module</span> </a> <a href="/chefgs/automate-kubernetes-deployment-using-terraform-and-github-actions-3m5c" class="crayons-link crayons-link--contentful series-switcher__link " data-preload-image="" title="Published May 22 '23"> <span class="series-switcher__num">8</span> <span class="series-switcher__title">Automate Kubernetes Deployment using Terraform and GitHub Actions</span> </a> </div> </nav> <div class="crayons-article__body text-styles spec__body" data-article-id="502724" id="article-body"> <h1> <a name="table-of-content" href="#table-of-content"> </a> Table of Content </h1> <ul> <li><a href="#introduction">Introduction</a></li> <li><a href="#bit-of-intro-into-terraform">Bit of intro into Terraform</a></li> <li><a href="#terraform-provider">Terraform Provider</a></li> <li><a href="#terraform-custom-provider">Terraform Custom Provider</a></li> <li><a href="#what-is-required-to-develop-custom-provider">What is required to develop Custom Provider</a></li> <li><a href="#install-and-configure-terraform">Install and Configure Terraform</a></li> <li> <a href="#how-to-develop-provider-code-with-go">How to develop provider code with Go</a> <ul> <li> <a href="#step-1-setting-up-go-develop-environment">Step 1 Setting up Go develop environment</a> </li> <li><a href="#step-2-custom-provider-source-code-details">Step 2 Custom Provider Source Code Details</a></li> <li><a href="#step-3-build-go-code-and-create-tf-provider-executable">Step 3 Build go code and create tf provider executable</a></li> <li><a href="#step-4-create-terraform-file">Step 4 Create terraform file</a></li> <li><a href="#step-5-testing-provider-create-and-destroy-resource">Step 5 Testing Provider Create and Destroy resource</a></li> </ul> </li> <li><a href="#bibliography-and-reference">Bibliography and Reference</a></li> </ul> <h2> <a name="introduction" href="#introduction"> </a> <em>Introduction</em> </h2> <p>We assume that the readers of this article has prior understanding and working knowledge in Terraform and has created resource provisioning TF files for various Cloud providers. But still....</p> <h2> <a name="bit-of-intro-into-terraform" href="#bit-of-intro-into-terraform"> </a> <em>Bit of intro into Terraform</em> </h2> <ul> <li>Terraform is a Cloud agnostic Infra as code technology and used to create immutable infrastructure. </li> <li>Terraform is used to create, manage, and update infrastructure resources such as physical machines, VMs, network switches, containers, and more. Almost any infrastructure type can be represented as a resource in Terraform.</li> <li>Deliver infrastructure as code with Terraform using declarative tf configuration files</li> <li>Plan and predict changes: Terraform provides an elegant user experience for operators to safely and predictably make changes to infrastructure</li> <li>Create reproducible infrastructure: Terraform makes it easy to re-use configurations for similar infrastructure, helping you avoid mistakes and save time.</li> </ul> <h2> <a name="terraform-provider" href="#terraform-provider"> </a> <em>Terraform Provider</em> </h2> <p>A provider is responsible for understanding API interactions and exposing resources. Most providers configure a specific infrastructure platform (either cloud or self-hosted). Providers can also offer local utilities for tasks like generating random numbers for unique resource names.</p> <h2> <a name="terraform-custom-provider" href="#terraform-custom-provider"> </a> <em>Terraform Custom Provider</em> </h2> <p>According to Terraform documentation,</p> <p>There are a few possible reasons for authoring a custom Terraform provider, such as:</p> <ul> <li><p>An internal private cloud whose functionality is either proprietary or would not benefit the open source community.</p></li> <li><p>A "work in progress" provider being tested locally before contributing back.</p></li> <li><p>Extensions of an existing provider</p></li> </ul> <p>Refer the Hashicorp Documentation on <a href="https://www.terraform.io/docs/extend/writing-custom-providers.html">writing custom providers</a></p> <h2> <a name="what-is-required-to-develop-custom-provider" href="#what-is-required-to-develop-custom-provider"> </a> <em>What is required to develop Custom Provider</em> </h2> <ol> <li>Just small enough Go development knowledge </li> <li>Resource creation supported by API calls from the respective provider</li> </ol> <h2> <a name="install-and-configure-terraform" href="#install-and-configure-terraform"> </a> <em>Install and Configure Terraform</em> </h2> <ul> <li>Refer here <a href="https://www.terraform.io/downloads.html">for installing terraform</a> </li> <li>Windows <ul> <li>Download and extract the terraform executable</li> <li>Add terraform executable path to ENV PATH variable</li> </ul> </li> <li>In Linux flavours, Copy the terraform executable in /usr/bin path to execute it from any path.</li> </ul> <h2> <a name="how-to-develop-provider-code-with-go" href="#how-to-develop-provider-code-with-go"> </a> <em>How to develop provider code with Go</em> </h2> <h3> <a name="step-1-setting-up-go-develop-environment" href="#step-1-setting-up-go-develop-environment"> </a> <em>Step 1 Setting up Go develop environment</em> </h3> <p><a href="https://dev.to/chefgs/getting-started-with-go-in-ubuntu-16-04-3b59">Refer my Dev community article</a></p> <p><a href="https://dev.to/chefgs/go-hello-world-program-17pk">Read my article on getting started with Go Hello World</a></p> <h3> <a name="step-2-custom-provider-source-code-details" href="#step-2-custom-provider-source-code-details"> </a> <em>Step 2 Custom Provider Source Code Details</em> </h3> <p>Please check out the provider source files from <a href="https://github.com/chefgs/terraform_repo/tree/main/custom_provider/tf_custom_provider">GitHub Repo Here</a></p> <ul> <li>Required source files for custom provider are, <ul> <li><code>main.go</code></li> <li> <code>provider.go</code> </li> <li> <code>resource_server.go</code> </li> </ul> </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>The code layout looks like this: . ├── main.go ├── provider.go ├── resource_server.go </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <ul> <li>Go entry point function is <code>main.go</code>. </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>// main.go package main import ( "github.com/hashicorp/terraform-plugin-sdk/plugin" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) func main() { plugin.Serve(&plugin.ServeOpts{ ProviderFunc: func() terraform.ResourceProvider { return Provider() }, }) } </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <ul> <li> <code>provider.go</code> will have the resource server function calls. </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>// provider.go package main import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) func Provider() *schema.Provider { return &schema.Provider{ ResourcesMap: map[string]*schema.Resource{ "customprovider_server": resourceServer(), }, } } </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <ul> <li>All the resource creation has to be coded in <code>resource_server.go</code>. This file will have the resource function declaration and definition like create, delete etc, it also gets the input params required to create resources. </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>// resource_server.go package main import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) func resourceServer() *schema.Resource { return &schema.Resource{ Create: resourceServerCreate, Read: resourceServerRead, Update: resourceServerUpdate, Delete: resourceServerDelete, Schema: map[string]*schema.Schema{ "num_sys": &schema.Schema{ Type: schema.TypeString, Required: true, }, }, } } func resourceServerCreate(d *schema.ResourceData, m interface{}) error { num_sys := d.Get("num_sys").(string) d.SetId(num_sys) /* API call to be added for respective provider. In case of developing provider for on-prem cloud or public cloud, that is not supported by terraform, add the API call to corresponding Resource creation API */ return resourceServerRead(d, m) } func resourceServerRead(d *schema.ResourceData, m interface{}) error { return nil } func resourceServerUpdate(d *schema.ResourceData, m interface{}) error { return resourceServerRead(d, m) } func resourceServerDelete(d *schema.ResourceData, m interface{}) error { return nil } </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <ul> <li>Details regarding the custom provider code in <code>resource_server.go</code>: <ul> <li>Our code repo example implemented with mock resource creation for the provider called 'customprovider'. </li> <li>In real-time case, it has to be changed for the provider name of respective cloud or on-premises server. </li> <li>Most of providers have API calls to be consumed for resource operation like create/update/delete etc.. So We need to define the logic of resource operations like create and delete using the custom provider api calls, to apply the terraform template.</li> <li>Please add the API call implementation in the <code>/* commented out */</code> section in <code>resource_server.go</code> </li> </ul> </li> </ul> <h3> <a name="step-3-build-go-code-and-create-tf-provider-executable" href="#step-3-build-go-code-and-create-tf-provider-executable"> </a> <em>Step 3 Build go code and create tf provider executable</em> </h3> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>cd tf_custom_provider/ go mod init go mod tidy go build -o terraform-provider-customprovider </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <p>Please note,<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>Third-party plugins (both providers and provisioners) can be manually installed into the user plugins directory Located at %APPDATA%\terraform.d\plugins on Windows and ~/.terraform.d/plugins on other systems. Copy the custom provider executable created in the step above to Terraform plugin directory </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <ul> <li>After adding the logic for resource operations in <code>resource_server.go</code>, our custom provider is ready to get tested</li> </ul> <h3> <a name="step-4-create-terraform-file" href="#step-4-create-terraform-file"> </a> <em>Step 4 Create terraform file</em> </h3> <p>Test the provider by creating <code>main.tf</code>, by providing the resource inputs. In our sample just the number of server count added as an input parameter for demo purpose.<br> Create or Edit <code>main.tf</code> file with code to create custom provider resource<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>resource "customprovider_server" "my-server-name" { num_sys = "2" } </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <h3> <a name="step-5-testing-provider-create-and-destroy-resource" href="#step-5-testing-provider-create-and-destroy-resource"> </a> <em>Step 5 Testing Provider Create and Destroy resource</em> </h3> <ul> <li>The custom provider executable should be placed inside the "~/.terraform.d/plugins" (in Linux server) path to enable the access to the custom provider functionality</li> <li>Execute the following Terraform commands to verify the custom provider functionalities we have added, </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>terraform init terraform plan terraform apply terraform destroy </code></pre> <div class="highlight__panel js-actions-panel"> <div class="highlight__panel-action js-fullscreen-code-action"> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title> <path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title> <path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path> </svg> </div> </div> </div> <h2> <a name="bibliography-and-reference" href="#bibliography-and-reference"> </a> <em>Bibliography and Reference</em> </h2> <p><a href="https://www.terraform.io/docs/index.html">Terraform Docs</a><br> <a href="https://learn.hashicorp.com/collections/terraform/providers">Custom Provider Lab Tutorial</a> <br> <a href="https://www.hashicorp.com/blog/writing-custom-terraform-providers">Custom Provider Easy Tutorial</a></p> </div> <nav class="series-switcher crayons-card crayons-card--secondary"> <header class="crayons-card__header"> <h2 class="crayons-subtitle-2"> <a href="/chefgs/series/9495">Terraform Tutorials (8 Part Series)</a> </h2> </header> <div class="series-switcher__list"> <a href="/chefgs/developing-terraform-custom-provider-49f2" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--active " data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4ebfe8olqh1omyxbj2x9.png" title="Published Oct 31 '20"> <span class="series-switcher__num">1</span> <span class="series-switcher__title">Developing Terraform Custom Provider for Terraform v0.12</span> </a> <a href="/chefgs/create-apache-web-server-in-aws-using-terraform-1fpj" class="crayons-link crayons-link--contentful series-switcher__link " data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0j1yvjylbe6jv53e7ta.png" title="Published Jun 19 '21"> <span class="series-switcher__num">2</span> <span class="series-switcher__title">Create Apache Web Server in AWS Using Terraform</span> </a> <a href="/chefgs/create-and-configure-google-cloud-instance-using-terraform-and-chef-3g01" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--inbetween" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fet46qubgi3xq6ylq3bk7.png" id="collection-link-inbetween" data-no-instant title="View more"> <span class="series-switcher__num">...</span> <span class="series-switcher__title">4 more parts...</span> </a> <a href="/chefgs/create-and-configure-google-cloud-instance-using-terraform-and-chef-3g01" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--hidden" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fet46qubgi3xq6ylq3bk7.png" title="Published Jul 15 '21"> <span class="series-switcher__num">3</span> <span class="series-switcher__title">Create and Configure Google Cloud Instance using Terraform and Chef</span> </a> <a href="/chefgs/developing-a-custom-provider-in-terraform-v013-49l8" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--hidden" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrxbfdsrqwgjx9yw8m6t.png" title="Published Nov 20 '21"> <span class="series-switcher__num">4</span> <span class="series-switcher__title">How to Develop a Custom Provider in Terraform v0.13+</span> </a> <a href="/aws-builders/create-aws-infrastructure-using-cdk-for-terraform-3eg5" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--hidden" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foj6x2ww0ogr0f2eg7lrk.png" title="Published Mar 24 '22"> <span class="series-switcher__num">5</span> <span class="series-switcher__title">Create AWS Infrastructure using CDK for Terraform</span> </a> <a href="/chefgs/deploy-kubernetes-resources-in-minikube-cluster-using-terraform-1p8o" class="crayons-link crayons-link--contentful series-switcher__link series-switcher__link--hidden" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnr00jj26rkboeu26mp2j.png" title="Published Jun 25 '22"> <span class="series-switcher__num">6</span> <span class="series-switcher__title">Deploy Kubernetes Resources in Minikube cluster using Terraform</span> </a> <a href="/aws-builders/create-amazon-eks-cluster-using-terraform-module-27p5" class="crayons-link crayons-link--contentful series-switcher__link " data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jt1dguvt2q9axxl7w0d.jpeg" title="Published Apr 18 '23"> <span class="series-switcher__num">7</span> <span class="series-switcher__title">Create Amazon EKS Cluster using Terraform Module</span> </a> <a href="/chefgs/automate-kubernetes-deployment-using-terraform-and-github-actions-3m5c" class="crayons-link crayons-link--contentful series-switcher__link " data-preload-image="" title="Published May 22 '23"> <span class="series-switcher__num">8</span> <span class="series-switcher__title">Automate Kubernetes Deployment using Terraform and GitHub Actions</span> </a> </div> </nav> <div class="js-billboard-container body-billboard-container" data-async-url="/chefgs/developing-terraform-custom-provider-49f2/bb-2/post_body_bottom"></div> </div> <section id="comments" data-follow-button-container="true" data-updated-at="2025-02-17 15:53:32 UTC" class="text-padding mb-4 border-t-1 border-0 border-solid border-base-10"> <header class="relative flex justify-between items-center mb-6"> <div class="flex items-center"> <h2 class="crayons-subtitle-1"> Top comments <span class="js-comments-count" data-comments-count="0">(0)</span> </h2> </div> <div id="comment-subscription" class="print-hidden"> <div class="crayons-btn-group"> <span class="crayons-btn crayons-btn--outlined">Subscribe</span> </div> </div> </header> <div id="billboard_delay_trigger"></div> <div id="comments-container" data-testid="comments-container" data-commentable-id="502724" data-commentable-type="Article" data-has-recent-comment-activity="false"> <div id="response-templates-data" class="hidden"></div> <form class="comment-form print-hidden" id="new_comment" action="/comments" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" autocomplete="off" /> <input type="hidden" name="authenticity_token" value="NOTHING" id="new_comment_authenticity_token"> <input value="502724" autocomplete="off" type="hidden" name="comment[commentable_id]" id="comment_commentable_id" /> <input value="Article" autocomplete="off" type="hidden" name="comment[commentable_type]" id="comment_commentable_type" /> <span class="crayons-avatar m:crayons-avatar--l mr-2 shrink-0"> <img src="https://media2.dev.to/dynamic/image/width=256,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" width="32" height="32" alt="pic" class="crayons-avatar__image overflow-hidden" id="comment-primary-user-profile--avatar" loading="lazy" /> </span> <div class="comment-form__inner"> <div class="comment-form__field" data-tracking-name="comment_form_textfield"> <textarea placeholder="Add to the discussion" onfocus="handleFocus(event)" onkeyup="handleKeyUp(event)" onkeydown="handleKeyDown(event)" oninput="handleChange(event)" id="text-area" required="required" class="crayons-textfield comment-textarea crayons-textfield--ghost" aria-label="Add a comment to the discussion" name="comment[body_markdown]"> </textarea> </div> <div class="response-templates-container crayons-card crayons-card--secondary p-4 mb-4 comment-form__templates fs-base hidden"> <header class="mb-3"> <button type="button" class="crayons-btn personal-template-button active" data-target-type="personal" data-form-id="new_comment">Personal</button> <button type="button" class="crayons-btn moderator-template-button hidden" data-target-type="moderator" data-form-id="new_comment">Trusted User</button> </header> <div class="personal-responses-container"> </div> <div class="moderator-responses-container hidden"> </div> <a target="_blank" rel="noopener nofollow" href="/settings/response-templates"> Create template </a> <p>Templates let you quickly answer FAQs or store snippets for re-use.</p> </div> <div class="comment-form__preview text-styles text-styles--secondary" id="preview-div"></div> <div class="comment-form__buttons mb-4"> <button type="submit" class="crayons-btn mr-2 js-btn-enable" onclick="validateField(event)" data-tracking-name="comment_submit_button" disabled>Submit</button> <button type="button" class="preview-toggle crayons-btn crayons-btn--secondary comment-action-preview js-btn-enable mr-2" data-tracking-name="comment_preview_button" disabled>Preview</button> <a href="/404.html" class="dismiss-edit-comment crayons-btn crayons-btn--ghost js-btn-dismiss hidden">Dismiss</a> </div> </div> <div class="code-of-conduct" id="toggle-code-of-conduct-checkbox"></div> </form> <div class="comments" id="comment-trees-container"> </div> </div> <div class="align-center"> <nav class="fs-s align-center block" aria-label="Conduct controls"> <a href="/code-of-conduct" class="crayons-link crayons-link--secondary">Code of Conduct</a> <span class="opacity-25 px-2" role="presentation">•</span> <a href="/report-abuse" class="crayons-link crayons-link--secondary">Report abuse</a> </nav> </div> </section> <div id="hide-comments-modal" class="hidden"> <form id="hide-comments-modal__form" class="hide-comments-modal__form" data-type="json" action="/comments/hide" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="✓" autocomplete="off" /><input type="hidden" name="_method" value="patch" autocomplete="off" /><input type="hidden" name="authenticity_token" value="ZO5M--b997iC0eB_fkwaX1SzwAQdBUpEpRLeIj61nUjWH_jhjdbwsudvg8crj4QhIR2Jba8XZpsu64dIrTS3Pg" autocomplete="off" /> <div class="hide-comments-modal__content"> <p class="pb-2"> Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's <a id="hide-comments-modal__comment-permalink" href="#">permalink</a>. </p> <label class="crayons-field crayons-field--checkbox my-2"> <input name="hide_children" type="hidden" value="0" autocomplete="off" /><input class="hide_children crayons-checkbox" type="checkbox" value="1" name="hide_children" id="hide_children" /> <p class="crayons-field__label">Hide child comments as well</p> </label> <p class="pb-4 pt-2"> <button type="submit" class="crayons-btn"> Confirm </button> </p> </div> </form> <p class="fs-s color-base-60">For further actions, you may consider blocking this person and/or <a id="hide-comments-modal__report-link" href="/report-abuse">reporting abuse</a></p> </div> </article> <div class="pb-4 crayons-layout__comments-billboard"> <div class="js-billboard-container pb-4 crayons-layout__comments-billboard" data-async-url="/chefgs/developing-terraform-custom-provider-49f2/bb-2/post_comments"></div> </div> <section class="crayons-card crayons-card--secondary text-padding mb-4 print-hidden" id="bottom-content-read-next"> <h2 class="crayons-subtitle-1">Read next</h2> <a href="/jetthoughts/finding-the-right-co-founder-a-guide-for-startups-fei" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fcontenu.nyc3.digitaloceanspaces.com%2Fjournalist%2Fcbcb34bf-3397-488c-ae6e-28c8d89278b9%2Fthumbnail.jpeg" class="crayons-link mt-6 block"> <div class="flex items-center"> <span class="crayons-avatar crayons-avatar--xl m:crayons-avatar--2xl mr-4 shrink-0"> <img loading="lazy" alt="jetthoughts-dev profile image" class="crayons-avatar__image" width="100" height="100" src="https://media2.dev.to/dynamic/image/width=100,height=100,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F432482%2F8e0d29a4-85ee-4c5c-a549-20db3d431664.jpg" /> </span> <div> <h3 class="fs-xl mb-0 lh-tight">Finding The Right Co-Founder: A Guide For Startups</h3> <p class="opacity-75 pt-1"> JetThoughts Dev - <time datetime="2025-01-29T03:47:34Z">Jan 29</time> </p> </div> </div> </a> <a href="/andreik/trees-in-sql-4fp" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx5ehzje2z83oih6bcer7.jpg" class="crayons-link mt-6 block"> <div class="flex items-center"> <span class="crayons-avatar crayons-avatar--xl m:crayons-avatar--2xl mr-4 shrink-0"> <img loading="lazy" alt="andreik profile image" class="crayons-avatar__image" width="100" height="100" src="https://media2.dev.to/dynamic/image/width=100,height=100,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F276658%2F60ed9ead-7595-459e-876a-6ecbcf91bad2.jpg" /> </span> <div> <h3 class="fs-xl mb-0 lh-tight">Trees in SQL</h3> <p class="opacity-75 pt-1"> Andrej Kirejeŭ - <time datetime="2024-12-25T16:27:47Z">Dec 25 '24</time> </p> </div> </div> </a> <a href="/ebereplenty/building-rest-api-endpoints-with-django-rest-framework-a-step-by-step-guide-5g0e" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwggyh1onhkzoue2ugn5i.jpg" class="crayons-link mt-6 block"> <div class="flex items-center"> <span class="crayons-avatar crayons-avatar--xl m:crayons-avatar--2xl mr-4 shrink-0"> <img loading="lazy" alt="ebereplenty profile image" class="crayons-avatar__image" width="100" height="100" src="https://media2.dev.to/dynamic/image/width=100,height=100,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F313853%2Fbd1fb518-fbb7-46f7-9b42-84e74adc75b7.png" /> </span> <div> <h3 class="fs-xl mb-0 lh-tight">Building REST API Endpoints with Django REST Framework: A Step-by-Step Guide</h3> <p class="opacity-75 pt-1"> NJOKU SAMSON EBERE - <time datetime="2024-12-24T09:16:05Z">Dec 24 '24</time> </p> </div> </div> </a> <a href="/0x2e_tech/debugging-https-localhost-httponly-cookie-issues-6eb" data-preload-image="" class="crayons-link mt-6 block"> <div class="flex items-center"> <span class="crayons-avatar crayons-avatar--xl m:crayons-avatar--2xl mr-4 shrink-0"> <img loading="lazy" alt="0x2e_tech profile image" class="crayons-avatar__image" width="100" height="100" src="https://media2.dev.to/dynamic/image/width=100,height=100,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2566561%2Fbe86eea2-2324-4d30-a281-482230f6f6cc.png" /> </span> <div> <h3 class="fs-xl mb-0 lh-tight">Debugging HTTPS localhost: httponly cookie issues</h3> <p class="opacity-75 pt-1"> 0x2e Tech - <time datetime="2025-01-26T16:40:28Z">Jan 26</time> </p> </div> </div> </a> </section> </div> </main> <aside class="crayons-layout__sidebar-right" aria-label="Author details"> <div class="crayons-article-sticky grid gap-4 pb-4 break-word" id="article-show-primary-sticky-nav"> <div class="crayons-card crayons-card--secondary branded-7 p-4 pt-0 gap-4 grid" style="border-top-color: #4b4b4b;"> <div class="-mt-4"> <a href="/chefgs" class="flex"> <span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"> <img src="https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F303053%2Fd97f6bd8-5ba4-4e3d-a8ad-6efc603a645a.jpg" class="crayons-avatar__image" alt="" loading="lazy" /> </span> <span class="crayons-link crayons-subtitle-2 mt-5"> Saravanan Gnanaguru </span> </a> </div> <div class="print-hidden"> <button name="button" type="button" data-info="{"className":"User","style":"","id":303053,"name":"Saravanan Gnanaguru"}" class="crayons-btn follow-action-button whitespace-nowrap w-100 follow-user" aria-label="Follow user: Saravanan Gnanaguru" aria-pressed="false">Follow</button> </div> <div class="color-base-70"> Cloud DevOps and Infra as Code </div> <div class="user-metadata-details"> <ul class="user-metadata-details-inner"> <li> <div class="key"> Location </div> <div class="value"> India </div> </li> <li> <div class="key"> Pronouns </div> <div class="value"> he/him </div> </li> <li> <div class="key"> Work </div> <div class="value"> Architect </div> </li> <li> <div class="key"> Joined </div> <div class="value"> <time datetime="2019-12-29T03:54:52Z" class="date">Dec 29, 2019</time> </div> </li> </ul> </div> </div> <div class="crayons-card crayons-card--secondary"> <header class="crayons-card__header"> <h3 class="crayons-subtitle-2"> More from <a href="/chefgs">Saravanan Gnanaguru</a> </h3> </header> <div> <a class="crayons-link crayons-link--contentful" href="/chefgs/automate-kubernetes-deployment-using-terraform-and-github-actions-3m5c"> Automate Kubernetes Deployment using Terraform and GitHub Actions <div class="crayons-link__secondary -ml-1"> <span class="mr-1"><span class="opacity-50">#</span>githubhack23</span> <span class="mr-1"><span class="opacity-50">#</span>terraform</span> <span class="mr-1"><span class="opacity-50">#</span>kubernetes</span> <span class="mr-1"><span class="opacity-50">#</span>githubactions</span> </div> </a> <a class="crayons-link crayons-link--contentful" href="/chefgs/setup-harperdb-on-equinix-bare-metal-server-43eo"> Setup HarperDB on Equinix Bare Metal Server <div class="crayons-link__secondary -ml-1"> <span class="mr-1"><span class="opacity-50">#</span>harperdb</span> <span class="mr-1"><span class="opacity-50">#</span>database</span> <span class="mr-1"><span class="opacity-50">#</span>programming</span> <span class="mr-1"><span class="opacity-50">#</span>tutorial</span> </div> </a> <a class="crayons-link crayons-link--contentful" href="/aws-builders/create-amazon-eks-cluster-using-terraform-module-27p5"> Create Amazon EKS Cluster using Terraform Module <div class="crayons-link__secondary -ml-1"> <span class="mr-1"><span class="opacity-50">#</span>aws</span> <span class="mr-1"><span class="opacity-50">#</span>kubernetes</span> <span class="mr-1"><span class="opacity-50">#</span>awseks</span> <span class="mr-1"><span class="opacity-50">#</span>tutorial</span> </div> </a> </div> </div> </div> <div class="crayons-article-sticky grid gap-4 break-word js-billboard-container" data-async-url="/chefgs/developing-terraform-custom-provider-49f2/bb-2/post_sidebar"></div> </aside> </div> <div class="mod-actions-menu print-hidden"></div> <div data-testid="unpublish-post-modal-container" class="unpublish-post-modal-container hidden"></div> <div class="fullscreen-code js-fullscreen-code"></div> <script src="https://assets.dev.to/assets/followButtons-f2455d1f50a862b83fa006b1953e3a1644598781243cae25d3e75b13c04184fd.js" defer="defer"></script> <script src="https://assets.dev.to/assets/billboard-6709ca2ebd37469a929e96c3990f16af5c91856e9656385ea60125489e71deab.js" defer="defer"></script> <script src="https://assets.dev.to/assets/localizeArticleDates-70147c5c6bfe350b42e020ebb2a3dd37419d83978982b5a67b6389119bf162ac.js" defer="defer"></script> <script src="https://assets.dev.to/assets/articleReactions-79a44d82fb34a91c3987c24cfd3bcf2b0d38a02730b69ae6da297387d185f015.js" defer="defer"></script> <script> function activateRunkitTags() { if (!areAnyRunkitTagsPresent()) return var checkRunkit = setInterval(function() { try { dynamicallyLoadRunkitLibrary() if (typeof(RunKit) === 'undefined') { return } replaceTagContentsWithRunkitWidget() clearInterval(checkRunkit); } catch(e) { console.error(e); clearInterval(checkRunkit); } }, 200); } function isRunkitTagAlreadyActive(runkitTag) { return runkitTag.querySelector("iframe") !== null; }; function areAnyRunkitTagsPresent() { var presentRunkitTags = document.getElementsByClassName("runkit-element"); return presentRunkitTags.length > 0 } function replaceTagContentsWithRunkitWidget() { var targets = document.getElementsByClassName("runkit-element"); for (var i = 0; i < targets.length; i++) { if (isRunkitTagAlreadyActive(targets[i])) { continue; } var wrapperContent = targets[i].textContent; if (/^(<iframe src)/.test(wrapperContent) === false) { if (targets[i].children.length > 0) { var preamble = targets[i].children[0].textContent; var content = targets[i].children[1].textContent; targets[i].innerHTML = ""; var notebook = RunKit.createNotebook({ element: targets[i], source: content, preamble: preamble }); } } } }; function dynamicallyLoadRunkitLibrary() { if (typeof(dynamicallyLoadScript) === "undefined") return dynamicallyLoadScript("//embed.runkit.com") } activateRunkitTags(); </script> <div class="js-billboard-container pb-4 crayons-layout__comments-billboard" data-async-url="/chefgs/developing-terraform-custom-provider-49f2/bb-2/post_fixed_bottom"></div> <div id="runtime-banner-container"></div> </div> </div> <footer id="footer" class="crayons-footer print-hidden"> <div id="footer-container" class="crayons-footer__container"> <style> .long-bb-body { max-height: calc(100vh - 200px); overflow: hidden; } .long-bb-bottom { height: 180px; background: linear-gradient(to top, var(--card-bg), transparent); margin-top: -180px; position:relative; z-index: 5; } </style> <div style="" data-display-unit data-id="146443" data-category-click="click" data-category-impression="impression" data-context-type="home" data-special="nothing" data-article-id="" data-type-of="in_house"> <p style="font-weight: bold;margin-bottom: 10px"> Thank you to our Diamond Sponsor <a href="https://neon.tech/">Neon</a> for supporting our community. </p> </div> <p class="fs-s crayons-footer__description"> <a class="c-link c-link--branded fw-medium" aria-label="DEV Community Home" href="/">DEV Community</a> — A constructive and inclusive social network for software developers. With you every step of your journey. </p> <ul class="footer__nav-links flex gap-2 justify-center flex-wrap fs-s p-0" style="" /> <li class="footer__nav-link flex items-center"> <a href="/"> Home </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/++"> DEV++ </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/pod"> Podcasts </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/videos"> Videos </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/tags"> Tags </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/help"> DEV Help </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="https://shop.forem.com/"> Forem Shop </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/advertise"> Advertise on DEV </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/challenges"> DEV Challenges </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/showcase"> DEV Showcase </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/about"> About </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/contact"> Contact </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/free-postgres-database-tier"> Free Postgres Database </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/software-comparisons"> Software comparisons </a> <span class="dot ml-2"></span> </li> </ul> <ul class="footer__nav-links flex gap-2 justify-center flex-wrap fs-s p-0" style="" /> <li class="footer__nav-link flex items-center"> <a href="/code-of-conduct"> Code of Conduct </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/privacy"> Privacy Policy </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/terms"> Terms of use </a> <span class="dot ml-2"></span> </li> </ul> <div class="fs-s"> <p>Built on <a class="c-link c-link--branded" target="_blank" rel="noopener" href="https://www.forem.com">Forem</a> — the <a target="_blank" rel="noopener" class="c-link c-link--branded" href="https://dev.to/t/opensource">open source</a> software that powers <a target="_blank" rel="noopener" class="c-link c-link--branded" href="https://dev.to">DEV</a> and other inclusive communities.</p> <p>Made with love and <a target="_blank" rel="noopener" class="c-link c-link--branded" href="https://dev.to/t/rails">Ruby on Rails</a>. DEV Community <span title="copyright">©</span> 2016 - 2025.</p> </div> </div> </footer> <div id="snack-zone"></div> <div id="global-signup-modal" class="authentication-modal hidden"> <div class="authentication-modal__container"> <figure class="authentication-modal__image-container"> <img class="authentication-modal__image" src="https://media2.dev.to/dynamic/image/width=190,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" alt="DEV Community" loading="lazy" /> </figure> <div class="authentication-modal__content"> <p class="authentication-modal__description"> We're a place where coders share, stay up-to-date and grow their careers. </p> </div> <div class="authentication-modal__actions"> <a href="/enter" class="crayons-btn" aria-label="Log in" data-no-instant> Log in </a> <a href="/enter?state=new-user" class="crayons-btn crayons-btn--ghost-brand js-global-signup-modal__create-account" aria-label="Create new account" data-no-instant> Create account </a> </div> </div> </div> <script src="https://assets.dev.to/assets/signupModalShortcuts-0b25469b985100a01e94cbd7fccaf7f0a4d776e129aac65c766aa32cb28ab29a.js" defer="defer"></script> <div id="cookie-consent"></div> <div id="i18n-translations" data-translations="{"en":{"core":{"add_comment":"Add comment","beta":"beta","comment":"Comment","copy_link":"Copy link","edit_profile":"Edit profile","follow":"Follow","follow_back":"Follow back","following":"Following","like":"Like","loading":"loading...","reaction":"Reaction","report_abuse":"Report abuse","search":"Search","success_settings":"Successfully updated settings.","counted_organization":{"one":"%{count} organization","other":"%{count} organizations"},"counted_user":{"one":"%{count} person","other":"%{count} people"},"not_following":"You're not following anyone","following_everyone":"You're following %{details} (everyone)","you_are_following":"You're following","and":"and"}}}"></div> <div id="reaction-category-resources" class="hidden" aria-hidden="true"> <img data-name="Like" data-slug="like" data-position="1" src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18" /> <img data-name="Unicorn" data-slug="unicorn" data-position="2" src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18" /> <img data-name="Exploding Head" data-slug="exploding_head" data-position="3" src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18" /> <img data-name="Raised Hands" data-slug="raised_hands" data-position="4" src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18" /> <img data-name="Fire" data-slug="fire" data-position="5" src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18" /> </div> <script> var userSignedIn = false; if (document.readyState === 'complete' || document.readyState === 'interactive') { initAuth(); } else { document.addEventListener('DOMContentLoaded', initAuth); } function initAuth() { var paramToken = new URLSearchParams(window.location.search).get('jwt'); if (paramToken && !userSignedIn) { authenticateUser(paramToken); } else { var iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = 'https://forem.com/auth_pass/iframe'; document.body.appendChild(iframe); window.addEventListener('message', function(event) { if (event.origin !== 'https://forem.com' && event.origin !== window.location.origin) { return; } var data = event.data; if (data.authenticated && !userSignedIn) { authenticateUser(data.token); } else if(data.authenticated && window.ReactNativeWebView && window.ReactNativeWebView.postMessage) { window.ReactNativeWebView.postMessage(JSON.stringify({ action: 'login', token: data.token, })); } }); } function authenticateUser(token) { fetch('/auth_pass/token_login', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getMetaContent('csrf-token'), }, body: JSON.stringify({ token: token }), }) .then(function(response) { return response.json(); }) .then(function(data) { if (data.success) { if (document.head.querySelector('meta[name="user-signed-in"][content="false"]')) { // Reload the page to update the user's state location.reload(); } } }) .catch(function(error) { console.error('Error during authentication:', error); }); } function getMetaContent(name) { var element = document.querySelector('meta[name="' + name + '"]'); return element ? element.getAttribute('content') : ''; } } </script> </body> </html>