Skip to content

Commit

Permalink
Update getting started
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanjjung committed Dec 19, 2024
1 parent 121bee5 commit 4ced879
Showing 1 changed file with 42 additions and 26 deletions.
68 changes: 42 additions & 26 deletions docs/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ To use this module, you'll need to get through this checklist first:
* `Configure awscli <https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html>`_ with
your credentials and default region. (You do not have to install awscli, though you can
`read how to here <https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html>`_.
Some of these docs refer to helpful awscli commands.)
Some of these docs refer to helpful awscli commands.) The Pulumi AWS provider relies on the same configuration,
though, so you must create the config file.
* Set up an `S3 bucket`_ to store your Pulumi state in.

The `Troubleshooting`_ section has some details on how to work through some issues related to setup.
Expand All @@ -35,7 +36,8 @@ Quickstart

After ensuring you meet the above prerequisites, run the ``quickstart.sh`` script, adjusting the following command to
refer to your particular project details:
::

.. code-block:: bash
./quickstart.sh \
/path/to/project/root # The root of your code project where you want to set up a pulumi project
Expand Down Expand Up @@ -79,14 +81,15 @@ S3 bucket

Create an S3 bucket in which to store state for the project. You must have one bucket devoted to your project, but you
can store multiple stacks' state files in that one bucket. The bucket should not be public (treat these files as
sensitive), and it's a good idea to turn on versioning, as it can save you from some difficult situations down the road.
sensitive), and it's usually a good idea to turn on versioning.

The name of an S3 bucket is used as part of a global domain, and so your bucket name must be globally unique. A good way
to handle this is to include an organization name in your bucket name. As a template, you may use:
::

$ORG-$PROJECT_NAME-pulumi


Repo setup
^^^^^^^^^^

Expand All @@ -95,14 +98,16 @@ You probably already have a code repo with your application code in it. If not,
Create a directory there called ``pulumi`` and create a new project and stack in it. You'll need the name of the S3
bucket from the previous step here. If you are operating in an AWS region other than what is set as your default for
AWSCLI, be sure to ``export AWS_REGION=us-east-1`` or whatever else you may need to do to override that.
::

.. code-block:: bash
cd /path/to/pulumi/code
pulumi login s3://s3-bucket-name
pulumi new aws-python
Follow the prompts to get everything named.


Set up this module
^^^^^^^^^^^^^^^^^^

Expand All @@ -114,19 +119,21 @@ Ensure your pulumi code directory contains a ``requirements.txt`` file with at l
You can pin your code to a specific version of this module by appending ``@branch_name`` to that. For example:
::

git+https://github.com/thunderbird/[email protected].7
git+https://github.com/thunderbird/[email protected].9

Pulumi will need these requirements installed. On your first run of a ``pulumi preview`` command (or some others),
Pulumi will attempt to set up its working environment. If this fails, or you need to make adjustments later, you can
activate Pulumi's virtual environment to perform pip changes. Assuming Pulumi's virtual environment lives at ``venv``,
run:
::

.. code-block:: bash
source ./venv/bin/activate
pip install -U -r requirements.txt
You can now develop Python Pulumi code in that directory, referring to this module with imports such as these:
::

.. code-block:: python
import tb_pulumi
Expand Down Expand Up @@ -159,36 +166,39 @@ recommend some conventions here. Namely:
* The values these keys map to should themselves be mappings. This provides a convention where more than one of each
pattern are configurable. The keys here should be arbitrary but unique identifiers for the resources being configured.
F/ex: ``backend`` or ``api``.
* The values these keys map to should be a mapping where the keys are valid configuration options for the resources
being built. The full listing of these values can be found by browsing the documentation. A barebones example can be
found in our `configuration example <https://github.com/thunderbird/pulumi/blob/main/config.stack.yaml.example>`_.
* The values these keys map to should be a mapping where each key/value combo is a valid configuration option for the
resources being built. The full listing of these values can be found by browsing the :py:mod:`tb_pulumi`
documentation. A barebones example can be found in our `sample config
<https://github.com/thunderbird/pulumi/blob/main/config.stack.yaml.example>`_.


Define a ThunderbirdPulumiProject
"""""""""""""""""""""""""""""""""

In your ``__main__.py`` file, start with a simple skeleton (or use ``__main__.py.example`` to start):
::

.. code-block:: python
import tb_pulumi
project = tb_pulumi.ThunderbirdPulumiProject()
If you have followed the conventions outlined above, ``project`` is now an object with a key property, ``config``, which
gives you access to the config file's data. You can use this in the next step to feed parameters into resource
declarations.
If you have followed the conventions outlined above, ``project.config`` is now a dict representation of the YAML file.
You can use this in the next step to feed parameters into resource declarations.


Declare ThunderbirdComponentResources
"""""""""""""""""""""""""""""""""""""

A ``pulumi.ComponentResource`` is a collection of related resources. In an effort to follow consistent patterns across
infrastructure projects, the resources available in this module all extend a custom class called a
``ThunderbirdComponentResource``. If you have followed the conventions outlined so far, it should be easy to stamp out
common patterns with them by passing config options into the constructors for these classes.
A `Pulumi ComponentResource <https://www.pulumi.com/docs/reference/pkg/python/pulumi/#pulumi.ComponentResource>`_ is a
collection of related resources. In an effort to follow consistent patterns across infrastructure projects, the
patterns available in this module all extend a custom class called a :py:class:`tb_pulumi.ThunderbirdComponentResource`.
If you have followed the conventions outlined so far, it should be easy to stamp out infrastructure with them by passing
``project.config`` config options into the constructors for these classes.

.. note::
The `Quickstart`_ section provides a working minimal example of code that follows these patterns.


Implementing ThunderbirdComponentResources
""""""""""""""""""""""""""""""""""""""""""

Expand All @@ -197,7 +207,8 @@ So you want to develop a new pattern to stamp out? Here's what you'll need to do
* Determine the best place to put the code. Is there an existing module that fits the bill?
* Determine the Pulumi type string for it. This goes: ``org:module:class``. The ``org`` should be unique to your
organization. For Thunderbird projects, it should be ``tb``. The ``module`` will be the Python submodule you're
placing the new class in. The ``class`` is whatever you've called the class.
placing the new class in (f/ex, classes in ``network.py`` should use ``network`` here). The ``class`` is whatever
you've called the class.
* Design the class following these guidelines:
* The constructor should always accept, before any other arguments, the following positional options:
* ``name``: The internal name of the resource as Pulumi tracks it.
Expand All @@ -210,13 +221,17 @@ So you want to develop a new pattern to stamp out? Here's what you'll need to do
other resources, like a security group and its rules, not just an EC2 instance).
* The constructor may accept a final ``**kwargs`` argument with arbitrary meaning. Because the nature of a component
resource is to compile many other resources into one class, it is not implicitly clear what "everything else"
should apply to. If this is implemented, its function should be clearly documented in the class.
* The class should extend ``tb_pulumi.ThunderbirdComponentResource``.
* The class should call its superconstructor in the following way:
* ``super().__init__(typestring, name, project, opts=opts)``
* Any resources you create must have the ``parent=self`` ``pulumi.ResourceOption`` set.
should apply to. If this is implemented, its function should be clearly documented in the class. If this isn't
passed into the superconstructor, you will need to implement all superconstructor arguments into your constructor.
* The class should extend :py:class:`tb_pulumi.ThunderbirdComponentResource`.
* The class should be sure to make an appropriate call to its superconstructor, which ensures the resources can be
properly tracked in the project (and other things).
* Any resources you create must have the ``parent=self`` ``pulumi.ResourceOption`` set. Set an appropriate
``depends_on`` value.
* At the end of the ``__init__`` function, you must call ``self.finish()``, passing in a dictionary of ``outputs``
and one of ``resources`` (see :py:meth:`tb_pulumi.ThunderbirdComponentResource.finish`).
and one of ``resources`` (see :py:meth:`tb_pulumi.ThunderbirdComponentResource.finish`). For
:py:class:`tb_pulumi.monitoring.MonitoringGroup` derivatives, call this at the end of the
:py:meth:`tb_pulumi.monitoring.MonitoringGroup.monitor` function instead.


Troubleshooting
Expand All @@ -237,7 +252,8 @@ Check your default version:

If you need a newer Python, `download and install it <https://www.python.org/downloads/>`_. Then you'll have to set up
the virtual environment yourself with something like this:
::

.. code-block:: bash
virtualenv -p /path/to/python3.12 venv
./venv/bin/pip install -r requirements.txt
Expand Down

0 comments on commit 4ced879

Please sign in to comment.