Building a Stack¶
The Stack is the definition of your infrastructure that Opslib will manage.
It’s made up of components, with the root component being
an instance of Stack.
stack.py¶from opslib import Stack
stack = Stack(__name__)
Opslib tries to import a module named stack (which is why our file is
called stack.py). In the module, it looks for an object named stack.
The __name__ argument helps Opslib figure out where the code is defined, so
it can create its .opslib directory, next to stack.py, to store its
state.
Attaching components¶
To build up the stack, we attach components to it, by setting them as attributes:
from pathlib import Path
from opslib import LocalHost
stack.host = LocalHost()
stack.hello = stack.host.file(
path=Path("/tmp/hello.txt"),
content="Hello World!\n"
)
At this point, the host and hello components are attached to the stack,
and will be deployed when we run opslib - deploy.
$ opslib - deploy
$ cat /tmp/hello.txt
Hello World!
Defining components¶
Attaching everything to the root stack object doesn’t scale much, so we’ll want to organize components into higher level structures:
from opslib import Component, Prop
class Bucket(Component):
class Props:
host = Prop(LocalHost)
color = Prop(str)
def build(self):
self.file = self.props.host.file(
path=Path(f"/tmp/{self.props.color}.txt"),
content=f"A splash of {self.props.color}\n"),
)
stack.red = Bucket(host=stack.host, color="red")
stack.green = Bucket(host=stack.host, color="green")
stack.blue = Bucket(host=stack.host, color="blue")
The Bucket component receives two Props: host and color.
The component’s build() method creates
sub-components and attaches them. It’s called when the Bucket component is
attached to something (in our case, the stack).
Note
build() is not called when the
component is created, but rather later, when it’s attached. This means that
a detached component doesn’t have any of its child components created and
attached yet.