Pulumi's Automation API is the programmatic interface for driving pulumi programs from within your code. The package can be used for a number of use cases:
This jupyter notebook explores various facets of automation API itself and explores how to deploy infrastructure without ever leaving the notebook.
To run this example you'll need a few pre-reqs:
Alright, let's get started.
In addition to fine-grained building blocks, Automation API provides two out-of-the-box ways to work with Stacks:
Programs locally available on-disk and addressed via a filepath (local source):
stack = create_stack("myOrg/myProj/myStack", work_dir=os.path.join("..", "path", "to", "project"))
Programs defined as a function alongside your Automation API code (inline source):
def pulumi_program():
bucket = s3.Bucket("bucket")
pulumi.export("bucket_name", bucket.Bucket)
stack = create_stack("myOrg/myProj/myStack", program=pulumi_program)
Each of these creates a stack with access to the full range of Pulumi lifecycle methods (up/preview/refresh/destroy), as well as methods for managing config, stack, and project settings:
stack.set_config("key", ConfigValue(value="value", secret=True))
preview_response = stack.preview()
An inline program allows you to define your infrastructure within a function alongside your other code. Consider the following function called s3_static_site
. It creates an s3 bucket, sets it up as a basic static website and exports the URL.
import pulumi
from pulumi_aws import s3
def s3_static_site():
# Create a bucket and expose a website index document
site_bucket = s3.Bucket("s3-website-bucket", website=s3.BucketWebsiteArgs(index_document="index.html"))
index_content = """
<html>
<head><title>Hello S3</title><meta charset="UTF-8"></head>
<body>
<p>Hello, world!</p>
<p>Made with ❤️ with <a href="https://pulumi.com">Pulumi</a></p>
</body>
</html>
"""
# Write our index.html into the site bucket
s3.BucketObject("index",
bucket=site_bucket.id, # reference to the s3.Bucket object
content=index_content,
key="index.html", # set the key of the object
content_type="text/html; charset=utf-8") # set the MIME type of the file
# Set the access policy for the bucket so all objects are readable
s3.BucketPolicy("bucket-policy", bucket=site_bucket.id, policy={
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject"],
# Policy refers to bucket explicitly
"Resource": [pulumi.Output.concat("arn:aws:s3:::", site_bucket.id, "/*")]
},
})
# Export the website URL
pulumi.export("website_url", site_bucket.website_endpoint)
Now, let's define some functions to deploy and destroy our stacks.
from typing import List, Tuple, Optional, Dict
from pulumi import automation as auto
stack_name = "dev"
def noop():
pass
def deploy_project(project_name: str,
program: callable,
plugins: Optional[List[Tuple]] = None,
config: Optional[Dict[str, auto.ConfigValue]] = None):
# create (or select if one already exists) a stack that uses our inline program
stack = auto.create_or_select_stack(stack_name=stack_name,
project_name=project_name,
program=program)
if plugins:
for plugin in plugins:
stack.workspace.install_plugin(plugin[0], plugin[1])
print("plugins installed")
if config:
stack.set_all_config(config)
print("config set")
stack.refresh(on_output=print)
stack.up(on_output=print)
return stack
def destroy_project(project_name: str):
stack = auto.create_or_select_stack(stack_name=stack_name,
project_name=project_name,
program=noop)
stack.destroy(on_output=print)
stack.workspace.remove_stack(stack_name)
print(f"stack {stack_name} in project {project_name} removed")
Alright, we're ready to deploy our first project. Execute the code below and watch the output as your program progresses.
s3_site = deploy_project("my_first_project",
s3_static_site,
plugins=[("aws", "v4.0.0")],
config={"aws:region": auto.ConfigValue(value="us-west-2")})
Now that our stack is deployed, let's make sure everything was deployed correctly by making a request to the URL we exported.
outputs = s3_site.outputs()
url = f"http://{outputs['website_url'].value}"
import requests
site_content = requests.get(url).text
site_content
Cool! Looks like we got some HTML back. Let's display it in our notebook using IPython.
from IPython.core.display import HTML
HTML(site_content)
Alright, that looks much better. We can even open our website in a new browser tab.
import webbrowser
outputs = s3_site.outputs()
webbrowser.open(url)
Now that we're done testing everything out, we can destroy our stack.
destroy_project("my_first_project")