Skip to content

Ability to run a "setup" and "teardown" set of infrastructure, separate to tests. #56

@baolsen

Description

@baolsen

Can be assigned to me, just looking for some feedback beforehand.

Sometimes tests require that specific infrastructure is already created.

It isn't always possible or practical to create it within the same Terraform code-base, and the code needs to be split into multiple stages.

For example, we want to create a Postgres RDS database and add some users, then test that the users have correct access.

The Postgres provider for adding users requires information about the Postgres database. If the Postgres database and users are created in one script then the information about the database is only known after apply.

Typically we would have to split this into two steps, applying the first before applying the second.
1 - Create database
2 - Create users

For long-lived infrastructure this is fine, because we don't expect the database to be destroyed often.
When testing, however, we have transient infrastructure.

It would be helpful to be able to do a setup of infrastreucture like the database, prior to a set of tests, and a teardown after a set of tests.

Maybe it could look something like this, thought its a bit messy:

@terraform("create_rds_database", scope="session", replay=False)
@terraform("create_rds_users", scope="session", replay=False)
def test_users_1_terraform(create_rds_users, create_rds_database):
    # Test case 1

@terraform("create_rds_database", scope="session", replay=False)
@terraform("create_rds_users", scope="session", replay=False)
def test_users_2_terraform(create_rds_users, create_rds_database):
    # Test case 2

@terraform("create_rds_database", scope="session", replay=False)
@terraform("create_replication_for_rds", scope="session", replay=False)
def test_replication_1_terraform(create_rds_users, create_replication_for_rds):
       # Test case 3

I'm not sure this is possible with the current codebase, or even if this is a good approach to the problem.

Something using classes or module scopes might be easier to understand:


@terraform("create_rds_database", scope="session", replay=False)
class MyDatabaseTests():
     
     @terraform("create_rds_users", scope="session", replay=False)
     def test_users_1_terraform(create_rds_users, create_rds_database):
           # Test case 1

     
     @terraform("create_rds_users", scope="session", replay=False)
     def test_users_2_terraform(create_rds_users, create_rds_database):
           # Test case 2

    @terraform("create_replication_for_rds", scope="session", replay=False)
     def test_replication_1_terraform(create_rds_users, create_replication_for_rds):
            # Test case 3

Workaround:

This can be done by using separate Terraform code and terraform apply / destroy actions around the pytest action.
Maybe this is a recommended approach rather than allowing this as a feature.
Then maybe something to add to the documentation / user guide here since it is a bit of a complex case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions