Reference module from a module in separate Terraform projects - terraform

Is it possible with Terraform to have a directory structure like the following:
├── environments
│   └── production
│   ├── app1
│   ├── instances.tf
│   ├── app2
│   └── shared
│   ├── iam.tf
│   └── security_groups.tf
└── modules
└── iam
└── node
Where environments/production/{app1, app2, shared} all each have their own terraform state and each are independent of each other. However, from app1 and app2 I need to reference module output variables like security groups, IAM etc from shared.
So environments/production/shared/iam.tf looks like:
module "iam" {
source = "../../../modules/iam"
var1 = "foo"
var2 = "bar"
var3 = "car"
var4 = "nar"
}
How then, from app1, or app2 do I reference the instance of iam from shared?
environments/production/app1/instances.tf:
module "app1" {
source = "../../../modules/node"
iam_profile_id = { how do I reference the IAM module from shared here?
// shared.module.iam.profile_id?
}

Related

Bindgen failing because of relative paths in header file

I'm trying to build out some bindings for vmaf but i've been running into some issues. The header files and the .c files in the vmaf repository live in seperate folders. I'm having an issue where the main vmaf.h file references other .h files in the same directory:
#ifndef __VMAF_H__
#define __VMAF_H__
#include <stdint.h>
#include <stdio.h>
#include "libvmaf/compute_vmaf.h"
#include "libvmaf/model.h"
#include "libvmaf/picture.h"
#include "libvmaf/feature.h"
...
this results in me getting the following build error:
vmaf/libvmaf/include/libvmaf/libvmaf.h:25:10: fatal error: 'libvmaf/compute_vmaf.h' file not found. It looks to me that rust-bindgen is looking in the current working directory for the next header file when in reality it lives in a subdirectory in my project as a git submodule pointing to the vmaf git repository
Here's the folder structure
.
├── src # lib.rs lives here
├── target
│ └── debug
└── vmaf
├── libvmaf
│ ├── doc
│ ├── include
│ │ └── libvmaf # vmaf.h lives here along with other .h files
│ ├── src # various other .h files live here
│ │ ├── arm
│ │ ├── compat
│ │ ├── ext
│ │ ├── feature
│ │ └── x86
│ ├── test
│ └── tools
and here's my build.rs
extern crate meson;
use std::env;
use std::path::PathBuf;
fn main() {
//env::set_var("RUST_BACKTRACE", "1");
let build_path = PathBuf::from(env::var("OUT_DIR").unwrap());
_ = build_path.join("build");
let build_path = build_path.to_str().unwrap();
println!("cargo:rustc-link-lib=libvmaf");
println!("cargo:rustc-link-search=native={build_path}");
meson::build("vmaf/libvmaf", build_path);
let bindings = bindgen::Builder::default()
.header("vmaf/libvmaf/include/libvmaf/libvmaf.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings.write_to_file(out_path).expect("Couldn't write bindings!")
}
How can I get rust-bindgen to look in that directory rather than from my current working directory?
Should i use cargo:rustc-link-search and point it to the correct directory? Will that mess up linking to the library itself since i've already used that statement earlier to compile the meson project?
The answer ended up being the -I flag to clang arg
// Path to vendor header files
let headers_dir = PathBuf::from("vmaf/libvmaf/include");
let headers_dir_canonical = canonicalize(headers_dir).unwrap();
let include_path = headers_dir_canonical.to_str().unwrap();
// Generate bindings to libvmaf using rust-bindgen
let bindings = bindgen::Builder::default()
.header("vmaf/libvmaf/include/libvmaf/libvmaf.h")
.clang_arg(format!("-I{include_path}")) // New Stuff!
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings");

rust how to define an internal dependency?

I am trying to achieve the following, I have this project structure:
.
├── Cargo.lock
├── Cargo.toml
└── src
├── lib.rs
├── mesh
│ ├── gltf_loader
│ │ ├── Cargo.toml
│ │ ├── pluralize
│ │ └── src
│ └── mesh.rs
└── vulkan
├── core.rs
├── hardware_interface.rs
├── image.rs
├── memory.rs
├── mod.rs
├── pipeline.rs
├── renderer.rs
├── shader_program.rs
├── swapchain.rs
└── tools.rs
in here pluralize defines a procedural macro that is needed to compile gltf_loader but that needs to be kept hidden from all other dependencies. So I want to compile gltf loader as a "subcrate" then use that crate as a dependency for mesh.rs. Ideally without moving the directory structure.
To that effect I added this to the root toml:
[dependencies]
gltf_loader = { path = "src/mesh/gltf_loader" }
However if I do this and try to run an example, I get this error:
error: failed to get `gltf_loader` as a dependency of package `vulkan_bindings v0.1.0 (/home/makogan/rust_never_engine)`
Caused by:
failed to load source for dependency `gltf_loader`
Caused by:
Unable to update /home/makogan/rust_never_engine/src/mesh/gltf_loader
Caused by:
failed to parse manifest at `/home/makogan/rust_never_engine/src/mesh/gltf_loader/Cargo.toml`
Caused by:
can't find `proc-macros` bin at `src/bin/proc-macros.rs` or `src/bin/proc-macros/main.rs`. Please specify bin.path if you want to use a non-default path.
Why does this happen?
This id the full .toml:
[package]
name = "vulkan_bindings"
version = "0.1.0"
edition = "2021"
[lib]
name = "vulkan_bindings"
path = "src/lib.rs"
[dependencies]
# Rendering
ash = { version = "0.37.0" }
glfw = { version = "0.45.0", features = ["vulkan"] }
gpu-allocator = "0.18.0"
spirv_cross = { version = "0.23.1", features = ["glsl"] }
shaderc = "0.8.0"
# Math
nalgebra = "*"
nalgebra-glm = "0.3"
nalgebra-sparse = "0.1"
# json
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
data-url = "0.1.1"
# misc
paste = "1.0.8"
termcolor = "1.1.3"
regex = "1.6.0"
add_getters_setters = "1.1.2"
# internal
gltf_loader = { path = "src/mesh/gltf_loader" }

The package import path is different for dynamic codegen and static codegen

Here is the structure for src directory of my project:
.
├── config.ts
├── protos
│ ├── index.proto
│ ├── index.ts
│ ├── share
│ │ ├── topic.proto
│ │ ├── topic_pb.d.ts
│ │ ├── user.proto
│ │ └── user_pb.d.ts
│ ├── topic
│ │ ├── service.proto
│ │ ├── service_grpc_pb.d.ts
│ │ ├── service_pb.d.ts
│ │ ├── topic.integration.test.ts
│ │ ├── topic.proto
│ │ ├── topicServiceImpl.ts
│ │ ├── topicServiceImplDynamic.ts
│ │ └── topic_pb.d.ts
│ └── user
│ ├── service.proto
│ ├── service_grpc_pb.d.ts
│ ├── service_pb.d.ts
│ ├── user.proto
│ ├── userServiceImpl.ts
│ └── user_pb.d.ts
└── server.ts
share/user.proto:
syntax = "proto3";
package share;
message UserBase {
string loginname = 1;
string avatar_url = 2;
}
topic/topic.proto:
syntax = "proto3";
package topic;
import "share/user.proto";
enum Tab {
share = 0;
ask = 1;
good = 2;
job = 3;
}
message Topic {
string id = 1;
string author_id = 2;
Tab tab = 3;
string title = 4;
string content = 5;
share.UserBase author = 6;
bool good = 7;
bool top = 8;
int32 reply_count = 9;
int32 visit_count = 10;
string create_at = 11;
string last_reply_at = 12;
}
As you can see, I try to import share package and use UserBase message type in Topic message type. When I try to start the server, got error:
no such Type or Enum 'share.UserBase' in Type .topic.Topic
But when I changed the package import path to a relative path import "../share/user.proto";. It works fine and got server logs: Server is listening on http://localhost:3000.
Above is the usage of dynamic codegen.
Now, I switch to using static codegen, here is the shell script for generating the codes:
protoc \
--plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts \
--ts_out=./src/protos \
-I ./src/protos \
./src/protos/**/*.proto
It seems protocol buffer compiler doesn't support relative path, got error:
../share/user.proto: Backslashes, consecutive slashes, ".", or ".." are not allowed in the virtual path
And, I changed the the package import path back to import "share/user.proto";. It generated code correctly, but when I try to start my server, got same error:
no such Type or Enum 'share.UserBase' in Type .topic.Topic
It's weird.
Package versions:
"grpc-tools": "^1.6.6",
"grpc_tools_node_protoc_ts": "^4.1.3",
protoc --version
libprotoc 3.10.0
UPDATE:
repo: https://github.com/mrdulin/nodejs-grpc/tree/master/src
Your dynamic codegen is failing because you are not specifying the paths to search for imported .proto files. You can do this using the includeDirs option when calling protoLoader.loadSync, which works in a very similar way to the -I option you pass to protoc. In this case, you are loading the proto files from the src/protos directory, so it should be sufficient to pass the option includeDirs: [__dirname]. Then the import paths in your .proto files should be relative to that directory, just like when you use protoc.
You are probably seeing the same error when you try to use the static code generation because it is actually the dynamic codegen error; you don't appear to be removing the dynamic codegen code when trying to use the statically generated code.
However, the main problem you will face with the statically generated code is that you are only generating the TypeScript type definition files. You also need to generate JavaScript files to actually run it. The official Node gRPC plugin for proto is distributed in the grpc-tools package. It comes with a binary called grpc_tools_node_protoc, which should be used in place of protoc and automatically includes the plugin. You will still need to pass a --js_out flag to generate that code.

How to get data from BigQuery in React.js app?

What I want to do and the problem
I want to access a table in the BigQuery, but got error like
TypeError: fs.createReadStream is not a function
at GoogleAuth.getClient (googleauth.js:497)
at GoogleAuth.authorizeRequest (googleauth.js:530)
at BigQuery.makeAuthenticatedRequest (util.js:374)
at BigQuery.request_ (service.js:129)
at BigQuery.request (service.js:140)
at BigQuery.createJob (bigquery.js:942)
at BigQuery.wrapper (index.js:42)
at BigQuery.createQueryJob (bigquery.js:862)
at BigQuery.wrapper (index.js:42)
at BigQuery.query (bigquery.js:1264)
at index.js:69
at new Promise (<anonymous>)
at BigQuery.wrapper (index.js:54)
at Signup.handleClick (Signup.js:52)
at HTMLUnknownElement.callCallback (react-dom.development.js:336)
at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
at invokeGuardedCallback (react-dom.development.js:440)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:454)
at executeDispatch (react-dom.development.js:584)
at executeDispatchesInOrder (react-dom.development.js:609)
at executeDispatchesAndRelease (react-dom.development.js:713)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js:722)
at forEachAccumulated (react-dom.development.js:694)
at runEventsInBatch (react-dom.development.js:739)
at runExtractedPluginEventsInBatch (react-dom.development.js:880)
at handleTopLevel (react-dom.development.js:5803)
at batchedEventUpdates$1 (react-dom.development.js:24401)
at batchedEventUpdates (react-dom.development.js:1415)
at dispatchEventForPluginEventSystem (react-dom.development.js:5894)
at attemptToDispatchEvent (react-dom.development.js:6010)
at dispatchEvent (react-dom.development.js:5914)
at unstable_runWithPriority (scheduler.development.js:697)
at runWithPriority$2 (react-dom.development.js:12149)
at discreteUpdates$1 (react-dom.development.js:24417)
at discreteUpdates (react-dom.development.js:1438)
at dispatchDiscreteEvent (react-dom.development.js:5881)
My Codes
First, I want to check the code with simple code. There is a button and when clicked it, the handleClick function works. All element for access BigQuery are in this function for now.
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import PersonIcon from '#material-ui/icons/Person';
import Typography from '#material-ui/core/Typography';
import Container from '#material-ui/core/Container';
class Signup extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(event) {
const { BigQuery } = require('#google-cloud/bigquery');
const bigquery = new BigQuery({
projectId: '(PROJECT_ID)',
keyFilename: '../../credentials/(credential file name).json',
});
const query = `
SELECT *
FROM \`(PROJECT_ID).paper_list.user_auth_info\`;
`
bigquery.query(query)
.then(data => {
const rows = data[0];
rows.forEach(row => alert("Hello"));
})
.catch(err => console.log(err));
}
render() {
const { classes } = this.props;
return (
<Container
component="main"
maxWidth="xs"
className={classes.outer}
>
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<PersonIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign Up
</Typography>
<form className={classes.form} noValidate>
<Button
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={this.handleClick}
>
Sign Up
</Button>
</form>
</div>
</Container>
);
}
}
The directory structure is like following,
.
├── Dockerfile
├── README.md
├── app.yaml
├── credentials # <- credential file is in this directory
├── node_modules
├── package-lock.json
├── package.json
├── public
└── src
├── App.css
├── App.js
├── App.test.js
├── Main.js
├── components
│   ├── AddFile.js
│   ├── Footer.js
│   ├── Header.js
│   ├── Inner.js
│   ├── Login.js
│   ├── PaperFolder.js
│   ├── PaperInfo.js
│   ├── PaperLabels.js
│   ├── SearchResultTable.js
│   ├── SideBar.js
│   ├── Signup.js # <- the code above
│   ├── TopLinks.js
│   └── ToppageMain.js
├── images
│   └── maarten-van-den-heuvel-8EzNkvLQosk-unsplash.jpg
├── index.css
├── index.js
├── serviceWorker.js
How to fix this error?
Thanks to the comment by Blundering Philosopher, I could understand the problem.
The BigQuery should be accessed from server-side, but the React.js is front-end, this was the problem. I wrote the API server with Go, and resolved it.

Aliasing modules using NodeJS

Some context here: It's not that I cannot use Webpack, it's that I do not want to use Webpack. I would like to keep everything as "vanilla" as possible.
Currently when creating modules in a project you have to require them using either a relative or absolute path, for example in the following directory..
project/
├── index.js
├── lib/
│ ├── network/
│ │ request.js
│ │ response.js
├── pages/
│ ├── foo.js
Considering we're in index.js we would import request via
var networkRequest = require('./lib/network/request.js')
and if we're in foo.js we would import request via
var networkRequest = require('../lib/network/request.js')
What I'm wondering is that if there's any way to perhaps, set a local alias in Package.json or anywhere else like so:
localPackages = [
{ name: 'network-request', path: './lib/network/request.js' }
];
In which you could just do
var networkRequest = require('network-request')
From any file and it will provide the correct path.
Yep, that's what npm link is for. Native and out of the box.
You can also set local paths in package.json
{
"name": "baz",
"dependencies": {
"bar": "file:../foo/bar"
}
}

Resources