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

Target module callers when local path module is updated #1528

Merged
merged 21 commits into from
Mar 16, 2024

Conversation

exoego
Copy link
Contributor

@exoego exoego commented Feb 13, 2024

Probably adresses #245 partially.

Issue

Let's say we have directory structures below:

modules/
  foo/
    main.tf
    tfaction_module.yaml
  bar/
    main.tf
    tfaction_module.yaml
workspace/
  production/
    tfaction.yaml
    main.tf
  staging/
    tfaction.yaml
    main.tf
  development/
    tfaction.yaml
    main.tf

Workspaces prod, staging and development use local-path modules modules/foo and modules/bar.

If the module modules/foo/main.tf is updated, unfortunately, tfaction can not plan/apply on its use-sites (production, staging and development).
Users need to update workspace/production/main.tf and such slightly.

Solution

After this PR, tfaction can plan and apply on module callers (use-site) even if each caller is not changed.

This new behavior is disabled by default.
Users needs to configure it in trfaction-root.yaml:

update_local_path_module_caller:
  enabled: true

Implementation detail

  • hashicorp/terraform-config-inspect is used to list up all local-path modules
  • Based on the inspection result, list-module-callers action creates a mapping from a module name to its caller.
  • Based on this mapping, a module caller will also be targeted if its modules are updated.

@suzuki-shunsuke suzuki-shunsuke self-requested a review February 13, 2024 09:22
Copy link
Owner

@suzuki-shunsuke suzuki-shunsuke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!
I have several comments.

First, I really appreciate it if you write an issue or a discussion before sending a pull request.

Second, I'm sorry that the description of #245 isn't enough, but this issue is about not local-path modules but GitHub Source modules. As we mentioned in the blog post and the document, we're recommending GitHub Source Modules rather than local-path modules

Third, I don't think changes of local-path modules should be applied to all callers on the same pull request.

  • Sometimes you Some users would like to apply changes by separated pull requests and apply changes one by one.
  • The code owners may be different per caller.
  • You Some users may want to apply changes to the specific callers first. For example, you they may want to apply changes to develop environments first and apply changes to production environments later.
  • If the local-path module is used by a lot of callers, it may be hard to review the result of terraform plan

@suzuki-shunsuke
Copy link
Owner

Users need to update workspace/production/main.tf and such slightly.

Maybe you're aware, but you can also use target:<target> labels.
JFYI

@exoego
Copy link
Contributor Author

exoego commented Feb 13, 2024

Third, I don't think changes of local-path modules should be applied to all callers on the same pull request.

Sometimes you would like to apply changes by separated pull requests and apply changes one by one.

No, we want to apply changes to all callers in a single PR, in my organization.
Because, folks tend to

  • forget to update some of callers when they update a sub module, and
  • get confused when they update workspace X and the TF plan includes changes due to the sub module Y recently updated by someone else.

When we need to update callers granularly, we use GitHub module or other version-controlled options.

    source = "github.com/my-org/terraform-module-fooo?ref=v1.2.3"

I can understand other users may not need this new behavior.
I am happy to put this new behavior under a new input something like update_local_path_module_caller: boolean.

@suzuki-shunsuke
Copy link
Owner

  • forget to update some of callers when they update a sub module, and
  • get confused when they update workspace X and the TF plan includes changes due to the sub module Y recently updated by someone else.

I understand your motivation.

I can understand other users may not need this new behavior.

Yes, so I don't want to apply this change by default. Users would be surprised if we change the default behaviour.

I am happy to put this new behavior under a new input something like update_local_path_module_caller: boolean.

One of ideas is to add the setting like update_local_path_module_caller: boolean to tfaction-root.yaml.

@exoego
Copy link
Contributor Author

exoego commented Feb 14, 2024

@suzuki-shunsuke Added a new extensible configuration object:

update_local_path_module_caller: z.optional(
    z.object({
      enabled: z.optional(z.boolean()),
    }),
  ),

as same as update_related_pull_requests. 246a10d

@@ -39,15 +39,26 @@ runs:
env:
HEAD_SHA: ${{github.event.pull_request.head.sha}}

- run: go install github.com/hashicorp/terraform-config-inspect@latest
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should pin the version. latest is unstable and insecure.
And this step requires Go, so we should clarify the requirement.

We can also install this tool by aqua.

https://github.com/aquaproj/aqua-registry/tree/main/pkgs/hashicorp/terraform-config-inspect

In that case, we need to ask users to update aqua.yaml, which isn't ideal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pinned the version a7d4635

I did not touch aqua, since I am not familiar with aqua and you said it is not ideal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Golang dpendency declared in 1aba475

}

const tfDir = path.dirname(tfFile);
const inspection = JSON.parse(child_process.execSync(`/home/runner/go/bin/terraform-config-inspect --json ${tfDir}`).toString("utf-8"));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path to terraform-config-inspect depends on the environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added GOBIN/GOPATH detection.
3acf082

@@ -153,16 +153,22 @@ export const run = (input: Input): TargetConfig[] => {
}
}

const moduleCallerMap = JSON.parse(core.getInput("module_callers") || "{}");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't call core.getInput here to make the function easy to test.
Please call core.getInput in main instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that is nice.
Fixed in e150731

@suzuki-shunsuke
Copy link
Owner

Does the current implementation support nested modules?
If the working directory A calls the module B, and the module B calls the module C, and if the module C is updated,
is the job run on the working directory A?

id: global-config
- uses: suzuki-shunsuke/tfaction/list-module-callers@main
id: list-module-callers
if: steps.global-config.outputs.disable_update_local_path_module_caller == 'false'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the feature is enabled by default, but as I said I want to disable this feature by default.

#1528 (comment)

And I think the output name should be update_local_path_module_caller because the feature is disabled by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rnamed in f6d9d8b

@exoego exoego force-pushed the update-module-use-site branch from d061624 to e150731 Compare February 17, 2024 06:41
@exoego
Copy link
Contributor Author

exoego commented Feb 17, 2024

Does the current implementation support nested modules?
If the working directory A calls the module B, and the module B calls the module C, and if the module C is updated,
is the job run on the working directory A?

Yes, it does support nested module calls.
These functions supports nested module calls.
https://github.com/suzuki-shunsuke/tfaction/pull/1528/files#diff-303affc8621a9e2bb810064d3f0633fdf227ce745d68ea05a07ea8f0fd2415f3

@suzuki-shunsuke
Copy link
Owner

Does the current implementation support nested modules?
If the working directory A calls the module B, and the module B calls the module C, and if the module C is updated,
is the job run on the working directory A?

Yes, it does support nested module calls. These functions supports nested module calls. https://github.com/suzuki-shunsuke/tfaction/pull/1528/files#diff-303affc8621a9e2bb810064d3f0633fdf227ce745d68ea05a07ea8f0fd2415f3

I see. Thank you.

@exoego
Copy link
Contributor Author

exoego commented Mar 12, 2024

@suzuki-shunsuke Could you take a look again on this

@suzuki-shunsuke suzuki-shunsuke added the enhancement New feature or request label Mar 14, 2024
"@types/node": "20.11.8",
"@vercel/ncc": "0.38.1",
"typescript": "5.3.3",
"vitest": "^1.2.2"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use jest, not vitest.
I'm not familiar with vitest.
So we should unify the library to jest if there is no special reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with jest 8b1f1ca

Vitest is a very fast testing framework and its API/config is highly compatible with Jest.
https://vitest.dev/

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Thank you for your explanation.

I think it's okay to replace Jest with Vitest if Vitest is better than Jest.
But we should not do this in this pull request.
We should open another pull request.

@suzuki-shunsuke
Copy link
Owner

8d83b3e Specify the install path of terraform-config-inspect

@suzuki-shunsuke
Copy link
Owner

suzuki-shunsuke commented Mar 16, 2024

Release Note

Features

#1528 Support running CI against working directories where depend on a updated local path module

By default, tfaction runs CI on only working directories where any code is updated.
This means even if a working directory depends on a module out of the working directory and the module is updated, CI isn't run on the working directory.

e.g.

  • A working directory A depends on local path module B
  • Module B is located out of the working directory A
  • In a pull request C, working directory A isn't changed but the module B is changed
  • Then CI isn't run on the working directory A by default
working directory A/
modules/
  module B

This update enables you to run CI on the working directory A too.
The feature is disabled by default, so you have to enable the feature explicitly.

tfaction-root.yaml

update_local_path_module_caller:
  enabled: true

This feature depends on terraform-config-inspect, so you have to install it.
Same with other tools, you can install terraform-config-inspect with aqua.

e.g.

packages:
  - name: hashicorp/terraform-config-inspect
    version: a34142ec2a72dd916592afd3247dd354f1cc7e5c

In that case, Go is required.

If this feature is enabled, when a module is updated in a pull request, CI is run on working directories depending on the module.
The module dependency is checked recursively.
For example, in the above case if the module B depends on a module C and module C is updated in a pull request,
CI is run on the working directory A even if the working directory A and the module B aren't updated.

suzuki-shunsuke and others added 6 commits March 16, 2024 11:56
…t to a temporal directory

It seems that action can't refer files on other actions
You have to install terraform-config-inspect yourself
…ate-module-use-site

# Conflicts:
#	list-module-callers/test/lib.test.ts
@exoego
Copy link
Contributor Author

exoego commented Mar 16, 2024

@suzuki-shunsuke Replaced Vitest with Jest

@suzuki-shunsuke
Copy link
Owner

suzuki-shunsuke commented Mar 16, 2024

I changed how to install terraform-config-inspect.
tfaction doesn't install it automatically anymore, so you have to install it yourself.
As described in #1528 (comment) , you can install it with aqua.

I said,

In that case, we need to ask users to update aqua.yaml, which isn't ideal.

But this feature is disabled by default so users have to configure tfaction explicitly.
This isn't a breaking change.
So I think we can accept this change.

This has both pros and cons.

  • pros
    • We don't have to update terraform-config-inspect
    • We can remove the code to install terraform-config-inspect
    • users can change the version of terraform-config-inspect based on the version of Terraform
      • I'm not familiar with the compatibility of Terraform and terraform-config-inspect, but we don't care about it
  • cons
    • Users have to install terraform-config-inspect themselves
    • User have to update terraform-config-inspect themselves
    • Maybe some users keep using old terraform-config-inspect and we have to take care of old terraform-config-inspect

@suzuki-shunsuke
Copy link
Owner

suzuki-shunsuke Replaced Vitest with Jest

Thank you so much!

@suzuki-shunsuke suzuki-shunsuke merged commit 6a5ff89 into suzuki-shunsuke:main Mar 16, 2024
12 checks passed
@suzuki-shunsuke suzuki-shunsuke added this to the v1.3.0 milestone Mar 16, 2024
@suzuki-shunsuke
Copy link
Owner

@suzuki-shunsuke
Copy link
Owner

v1.3.0 is out 🎉
https://github.com/suzuki-shunsuke/tfaction/releases/tag/v1.3.0

@exoego exoego deleted the update-module-use-site branch March 16, 2024 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants