Including a built artifact in another target (Bazel, golang)
• aws-lambda, bazel, golang, pulumi
We use pulumi to do IaC and we use a monorepo with Bazel as the build tool. We have out modules set out as following
One of the requirements we have is to build a lambda module and then deploy it. The lambda module is a target being built by Bazel (golang, but shouldn't matter):
go_binary(
name = "lambda_module",
visibility = ["//visibility:public"],
)
We then have the iac module, which should get the built version of the above module, so that it can then upload it into lambda
go_binary(
name = "iac",
args = [
"-lambda_module",
"$(location //products/productA/module/lambda_module)",
],
data = ["//products/productA/module/lambda_module"],
visibility = ["//visibility:public"],
)
There are two key parameters here to note:
args
: We generate the path to the target module using ` //products/productA/module/lambda_module)`data
: We use the data tag to ensure that the built output is included when building/running this target
We then need to use runfiles support within golang to be ablet to identify the correct location for the built binary. The reason this part is complex is to be able to support multiple operating systems. I should caveat that I have only got this working on Linux, but Mac/Win shouldn't be too different.
package main
import (
_ "embed"
"flag"
"fmt"
"github.com/bazelbuild/rules_go/go/runfiles"
"path/filepath"
)
func main() {
var webhookAuth = flag.String("webhook_auth", "", "bin for webhook_auth")
flag.Parse()
fmt.Printf("param : %s \n", *webhookAuth)
path, err := runfiles.Rlocation(fmt.Sprintf("workspace_name/%s", *webhookAuth))
fmt.Printf("rLoc path: %s, err: %v \n", path, err)
symlinks, err := filepath.EvalSymlinks(path)
fmt.Printf("evaluated path: %s, err: %v \n", symlinks, err)
}
We use the flag module to retrieve the path passed in as a runtime parameter
We use runfiles.Rlocation
to pick up the "real" path to the file, prepending
the workspace name to the start. You can
define the workspace name
in the root WORKSPACE file with workspace(name = "workspace_name")
Finally, resolve the Symlink to get the actual file path
References
There are similar mechanisms to find the rLocation in other languages, a couple of which are described in its design document
There is some documentation in rules_go
around
accessing go_binary
from go_test
which I referenced and updated to get the above example
I found the above link from a stackoverflow post about feeding bazel output to another bazel rule