The Automation API allows us to create an API for our current infrastructure. Having a basic set of commands that we can invoke programmatically via an interface is a nice touch, but it may not seem like much of an improvement. However, this kind of interface enables uses like a self-service web portal for others to provision infrastructure, a set of happy-path infrastructure that can all be deployed via chatbot or via other programs, or even as part of automated responses to an incident page. As engineers, we love to provision our stacks via a quick call, and we also like to make it easy for others to provision the same infrastructure with a simpler interface. Our program here is a placeholder for these more advanced uses. Let's build the custom API for our tiny program.
## Scaffolding
Let's start out with scaffolding the code by importing the right libraries and doing a bit of conversion of our basic Pulumi commands (create, configure, refresh, destroy, and update) to code with the automation API library. We'll be working in the `infra` directory at this point.
First, clear out the {{<langfile>}} file in the `infra` directory; from here on out, it's just there as a placeholder for the module itself in Python.
Next, add a file called `basic.py` into the `infra` directory with this code in it:
In that file, change the `<org>` value on line 122 to your own personal org on Pulumi (it should be your username).
We've made the most simple program you can make with the Automation API: a procedure for creating, updating, or deleting a specific stack. It's taking each step that the Pulumi CLI would take into its own function using the Automation API to define the actual actions. We'll use this scaffolding to ensure we can log at each step and raise errors properly (more on that later).
Here's your new directory structure:
```
learn-auto-api/
api/
time/
time_me.py
venv/
...
.gitignore
__main__.py
burner.py
Pulumi.yaml
requirements.txt
infra/
venv/
...
.gitignore
__main__.py
basic.py
Pulumi.yaml
requirements.txt
```
### Considerations with Destroy
The basics of such an API is taking the commands we call in the CLI and generalizing them to an interface that can be easily programmed. We also, however, would like to have the ability to destroy a stack locally as we'd like any future work locally to go through the API as well, but we really don't want any automation to be able to destroy a stack without human approval (unless perhaps it's an ephemeral stack for smoke testing). That's the part on lines 90 and 133 that defines a `destroy` variable, or flag, that can enable the destroy workflow.
## Automating Commands
Now that we have that basic layout, let's make our API and set it up to run! In the root of the project, add the following file as `infra_api.py`:
Change the `<org>` value on line 13 to your personal org on Pulumi (it should be your username).
Here's what the directory structure is now:
```
learn-auto-api/
api/
time/
time_me.py
venv/
...
.gitignore
__main__.py
burner.py
Pulumi.yaml
requirements.txt
infra/
venv/
...
.gitignore
__main__.py
basic.py
Pulumi.yaml
requirements.txt
infra_api.py
```
Lines 28 on in `infra_api.py` is all Falcon, a lightweight WSGI framework for REST APIs. But the part that we're really interested in from a Pulumi standpoint is on lines 11 to 25. Each endpoint that returns data from our "datacenter" calls that function and returns the data to the endpoint.
Now we've got some endpoints we can call. We've got a few considerations to take into account in the next module before we can start building with this code.