diff --git a/blog/terraform-post.md b/blog/terraform-post.md deleted file mode 100644 index 5aa35e94..00000000 --- a/blog/terraform-post.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: AEP Terraform Provider -date: 2025-03-31 -authors: - - name: Alex Stephen - - name: Marsh Gardiner ---- - -A core thesis of the AEP project has been that API design constraints can -facilitate the creation (and maintenance\!) of API client tools. In many -companies, teams are staffed to build out CLI tools, Terraform providers, UIs, -LLM agents, and various other tools that act as thin layers on top of a -company's APIs. The AEP project aims to ensure that these tools can be easily -generated on top of our API design, ensuring that companies can move faster -with less overall effort. We’re excited to launch our first version of a -[fully auto-generated Terraform provider](https://github.com/aep-dev/terraform-provider-aep) -based off the AEPs. - -![][image1] - -# What is Terraform? - -Terraform is a powerful Infrastructure-as-Code (IaC) tool that allows you to -define and manage your infrastructure using code. Infrastructure-as-Code, in -general, is the practice of managing and provisioning infrastructure through -machine-readable definition files rather than through manual processes. This -means you can automate the creation, modification, and deletion of resources -across various cloud providers and on-premises environments, ensuring -consistency, repeatability, and version control. - -Cloud companies often build out Terraform providers, which are responsible for -establishing differences between the cloud and the user's intent, determining -which API requests are necessary, making those requests, and handling any -follow-up actions. - -# How do the AEPs help with this? - -Most companies must staff engineers just to maintain their Terraform provider. -However, making AEP-compliant APIs can give you providers for no additional -effort beyond writing the API! Let's take a look at a pseudocode version of the -Terraform lifecycle. - -```python -userIntention := GetTerraformPlan() -currentState := ReadResource(userIntention) - -if currentState != null: - if user wishes to delete: - DeleteResource(currentState) - else if currentState != userIntention: - UpdateResource(userIntention) -else: - CreateResource(userIntention) -``` - -Two different sets of problems emerge and the AEPs are well-suited for solving -both of them. - -The first set of problems revolves around the grouping and calling of APIs. -There's a variety of tools in the market that will call an API method given a -set of parameters and an OpenAPI description (or even just a URL). Terraform -doesn't expose individual API methods, but instead exposes a resource schema. -This raises a variety of questions when developing a Terraform provider: - -- What are my resources? -- How do I know which API methods to call for a given resource? -- Is there a single API method that can be called for each CRUD operation, or - will I need to chain together API calls to achieve my result? -- How do I derive my resource schema from four distinct CRUD APIs? Is it simply - the union of all the body parameters from the four CRUD API methods? - -AEP APIs are resource-oriented by default, so just following the AEPs can -address all of the problems above. The Terraform provider can "know" which API -methods should be called and how they relate to each other. - -# What about API responses? - -The second set of problems comes from reading API responses. In the pseudocode -above, the Read response needs to be parsed and checked against the Terraform -plan. This means that the Terraform provider needs to understand the -relationship between the API response (beyond simple error checking) and the -user's intention. More questions emerge: - -- Does the response of the Read API match the resource schema? What changes - need to be made to match the Read API response to the potential resource - schema? -- Are there multiple ways that the server will accept a single value? If so, - how can I be sure that two semantically equivalent values do not result in a - diff against the Terraform plan? -- If a boolean value does not appear in the JSON response, does that mean it's - `false`? (And likewise for numeric values being `0`, string values being the - empty string, and so on.) - -Many of these questions come down to the preference of the API developer. In -fact, some of them cannot be defined by an API schema\! The AEPs encode these -differences in our specification, so that tools like our Terraform provider can -make assumptions about how to parse the responses of our APIs. - -# The AEP Terraform Provider - -The [AEP Terraform provider](https://github.com/aep-dev/terraform-provider-aep) -solves these problems. The provider is a template that can be pointed to any -OpenAPI spec that features APIs complying with the AEPs. Since the APIs are -resource-oriented and AEP-compliant, the provider is able to create a resource -schema at runtime that perfectly matches the APIs. Did your team build a new -feature? Just update your OpenAPI spec and the provider will add it without -users having to update their providers. - -Users are able to send over arbitrary headers so that the provider will work -with any authentication solution you may have. - -When users run `terraform apply`, the provider automatically knows how to -create Create, Read, Update, and Delete requests, handle authentication, and -return errors. More crucially, it understands how to handle the responses from -those requests. The provider understands what values to expect from the Get -requests and the proper way to handle difference checking against the user's -intention. - -# What comes next? - -While the Terraform provider lifecycle appears simple at first glance, the -details contain a deceptive amount of detail. This is detail that can only be -learned through trial-and-error, which is difficult when APIs are often only -designed once. - -By building out the Terraform provider, we're even more convinced than ever -that the AEP specification can prove the thesis that client tooling can be more -easily built on top of consistent APIs. - -[image1]: - data:image/png;base64,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 diff --git a/blog/terraform-post.mdx b/blog/terraform-post.mdx new file mode 100644 index 00000000..4a7e975d --- /dev/null +++ b/blog/terraform-post.mdx @@ -0,0 +1,134 @@ +--- +title: AEP Terraform Provider +date: 2025-03-31 +authors: + - name: Alex Stephen + - name: Marsh Gardiner + +import {Image} from 'astro:assets'; +import terraformImage from './terraform-image.png'; +--- + +A core thesis of the AEP project has been that API design constraints can +facilitate the creation (and maintenance\!) of API client tools. In many +companies, teams are staffed to build out CLI tools, Terraform providers, UIs, +LLM agents, and various other tools that act as thin layers on top of a +company's APIs. The AEP project aims to ensure that these tools can be easily +generated on top of our API design, ensuring that companies can move faster +with less overall effort. We’re excited to launch our first version of a +[fully auto-generated Terraform provider](https://github.com/aep-dev/terraform-provider-aep) +based off the AEPs. + +A pipeline showing AEP APIs becoming a Terraform provider + +# What is Terraform? + +Terraform is a powerful Infrastructure-as-Code (IaC) tool that allows you to +define and manage your infrastructure using code. Infrastructure-as-Code, in +general, is the practice of managing and provisioning infrastructure through +machine-readable definition files rather than through manual processes. This +means you can automate the creation, modification, and deletion of resources +across various cloud providers and on-premises environments, ensuring +consistency, repeatability, and version control. + +Cloud companies often build out Terraform providers, which are responsible for +establishing differences between the cloud and the user's intent, determining +which API requests are necessary, making those requests, and handling any +follow-up actions. + +# How do the AEPs help with this? + +Most companies must staff engineers just to maintain their Terraform provider. +However, making AEP-compliant APIs can give you providers for no additional +effort beyond writing the API! Let's take a look at a pseudocode version of the +Terraform lifecycle. + +```python +userIntention := GetTerraformPlan() +currentState := ReadResource(userIntention) + +if currentState != null: + if user wishes to delete: + DeleteResource(currentState) + else if currentState != userIntention: + UpdateResource(userIntention) +else: + CreateResource(userIntention) +``` + +Two different sets of problems emerge and the AEPs are well-suited for solving +both of them. + +The first set of problems revolves around the grouping and calling of APIs. +There's a variety of tools in the market that will call an API method given a +set of parameters and an OpenAPI description (or even just a URL). Terraform +doesn't expose individual API methods, but instead exposes a resource schema. +This raises a variety of questions when developing a Terraform provider: + +- What are my resources? +- How do I know which API methods to call for a given resource? +- Is there a single API method that can be called for each CRUD operation, or + will I need to chain together API calls to achieve my result? +- How do I derive my resource schema from four distinct CRUD APIs? Is it simply + the union of all the body parameters from the four CRUD API methods? + +AEP APIs are resource-oriented by default, so just following the AEPs can +address all of the problems above. The Terraform provider can "know" which API +methods should be called and how they relate to each other. + +# What about API responses? + +The second set of problems comes from reading API responses. In the pseudocode +above, the Read response needs to be parsed and checked against the Terraform +plan. This means that the Terraform provider needs to understand the +relationship between the API response (beyond simple error checking) and the +user's intention. More questions emerge: + +- Does the response of the Read API match the resource schema? What changes + need to be made to match the Read API response to the potential resource + schema? +- Are there multiple ways that the server will accept a single value? If so, + how can I be sure that two semantically equivalent values do not result in a + diff against the Terraform plan? +- If a boolean value does not appear in the JSON response, does that mean it's + `false`? (And likewise for numeric values being `0`, string values being the + empty string, and so on.) + +Many of these questions come down to the preference of the API developer. In +fact, some of them cannot be defined by an API schema\! The AEPs encode these +differences in our specification, so that tools like our Terraform provider can +make assumptions about how to parse the responses of our APIs. + +# The AEP Terraform Provider + +The [AEP Terraform provider](https://github.com/aep-dev/terraform-provider-aep) +solves these problems. The provider is a template that can be pointed to any +OpenAPI spec that features APIs complying with the AEPs. Since the APIs are +resource-oriented and AEP-compliant, the provider is able to create a resource +schema at runtime that perfectly matches the APIs. Did your team build a new +feature? Just update your OpenAPI spec and the provider will add it without +users having to update their providers. + +Users are able to send over arbitrary headers so that the provider will work +with any authentication solution you may have. + +When users run `terraform apply`, the provider automatically knows how to +create Create, Read, Update, and Delete requests, handle authentication, and +return errors. More crucially, it understands how to handle the responses from +those requests. The provider understands what values to expect from the Get +requests and the proper way to handle difference checking against the user's +intention. + +# What comes next? + +While the Terraform provider lifecycle appears simple at first glance, the +details contain a deceptive amount of detail. This is detail that can only be +learned through trial-and-error, which is difficult when APIs are often only +designed once. + +By building out the Terraform provider, we're even more convinced than ever +that the AEP specification can prove the thesis that client tooling can be more +easily built on top of consistent APIs. diff --git a/blog/terraform_image.png b/blog/terraform_image.png new file mode 100644 index 00000000..e5d65ccb Binary files /dev/null and b/blog/terraform_image.png differ