Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
baolsen opened this issue Oct 14, 2022 · 2 comments

Comments

@baolsen
Copy link
Contributor

baolsen commented Oct 14, 2022

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.

@kapilt
Copy link
Contributor

kapilt commented Dec 20, 2022

hmmm. this notion does also conflict with the auto teardown on apply failure if some state is pre-existing. there's also a notion missing in the example of state passing, ie output of one module feeding in as params to the other, re db endpoint/user/credentials. with the variable stuff some of that could be expressed but would require referencing the injected fixture name in globals to express dependencies ie create rds fixture created before create user/replication, although we could add a helper function for referencing so its more readable. it does make me wonder if this feel better using the terraform wrapper directly as a library vs a fixture as well. re a python interface for chained construction, this issue tries to capture an idea for it #43

@kapilt
Copy link
Contributor

kapilt commented Mar 20, 2023

as as simpler consideration of getting to the goal, we should have a pass through skip parameter for tests that want to bypass any fixture setup or teardown, albeit fixture is mostly decorative at that point outside of replay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants