Hashicorp Packer: ways to output a variable/local string value to a file - packer

I have some Packer templates which generate the content for configuration files which I then need to output to a configuration file. The end goal is to upload these files to the remote machine and then use the shell provisioner, but I can't seem to figure out the correct way of doing this. My current solution relies on a local shell provisioner to write the files, then I upload them to the remote, and then run the remote provisioner.
Something like,
locals {
foo = "bar"
foo_generated = templatefile("${path.root}/template-which-uses-foo.pkrtpl", foo)
}
provisioner "shell-local" {
inline = [
"cat >${path.root}/generated/foo.conf <<'STR'\n${local.foo_generated}"
]
}
provisioner "file" {
source = "${path.root}/generated/"
destination = "/tmp/"
}
provisioner "shell" {
inline = [
"/tmp/do-something-with-foo-conf.sh",
]
}
While this works, the file generation looks very awkward, and I want to simplify it and make it more robust.
I initially started with defining sourcees for configuration file (there are many of them), in addition to the "base" ec2 source. However, from the logs it looked like Packer runs provisioners for each source inside of the build block, so it didn't seem like a good idea.
Are there better options to accomplish this?

Related

Specifying input.json file from another directory for use in opa test

I am new to opa/rego and have an opa test that I would like to run. Within that test .rego file, I would like to use an input.json file from a different directory. Is there a way to specify that file within a "with input as _____" statement within the test file? i.e.
test_allow {
allow with input as <path-to-file>
}
My thoughts so far have lead me to trying the -b option but the directories are pretty far apart and I do not want a bundle that large and dependent. Additionally, I have thought about the import statements but I do not have the "-i" option within the opa test subcommand. I've also tried specifying each file (the .rego policy file, the .rego test file, and an input file) within the opa test subcommand to no avail.
Any help is greatly appreciated
OPA, and by extension the OPA test runner, doesn't really consider files at the time of policy evaluation. When OPA starts, all the files/directories pointed out by the command are merged under the data attribute, and may then be referenced byt their path, e.g. data.my-mocks.mock1, and so on.
If you want to include "test data" in your tests, you could keep those files in a directory included when running the opa test command. Since all data files are merged though, you'll need to ensure there aren't conflicting paths in those files. This is commonly accomplished by using a unique "top level" attribute per item. Something like:
{
"mock1": {
"item": "here"
},
"mock2": {
"item": "here"
}
}
You may then reference this in your tests like you suggested:
test_allow {
allow with input as data.mock1.item
}

Grunt Uglify files from list in external document

I have a module system, which can be controlled via an admin UI, developers can enable or disable features and the task runner then takes care of preparing all UI assets into single files to load on the front-end.
With SASS, I can programmatically control the index.scss file to be compiled, meaning that this is simple enough - however, with JS I don't find the same option, yet.
The idea is to avoid any file duplication, manipulation or movement, to reduce complexity, avoid issues and also to speed up the task runner, which quickly gets bloated and slowed down.
As the process begins with a save routine, I can collect data about the current "active" modules and store this is any file format - json, csv, whatever - I would then like to load that config from the file in the Gruntfile - which might be continually watching ( in case it's a problem that config can only be loaded once? -- the data would need to be grabbed again fresh before each compilation ).
simple example:
*module.json
{"js":["modal.js","toast.js","tab.js","collapse.js","form.js","toggle.js","gallery.js","helper.js","scrollspy.js","scroll.js","lazy.js","javascript.js","comment.js","push.js","nprogress.js","consent.js","search.js","anspress.js","localize.js"]}
*Gruntfile.js
// ------- configuration ------- ##
module.exports = function(grunt) {
grunt.initConfig({
// load modules ##
modules: grunt.file.readJSON('module.json'),
'uglify': {
// options etc ##
files:{
'library/asset/js/module.min.js' : '<%= modules.js %>'
}
}
});
// Development Tasks ##
grunt.registerTask(
'default'
, [ 'uglify' ]
);
}
This config runs, but does not load the data from JSON correctly - Grunt says:
Destination library/asset/js/module.min.js not written because src
files were empty.
I know Grunt can read the JS, as I can do something like the following:
*terminal
$ grunt config
Running "config" task
["modal.js","toast.js","tab.js","collapse.js","form.js","toggle.js","gallery.js","helper.js","scrollspy.js","scroll.js","lazy.js","javascript.js","comment.js","push.js","nprogress.js","consent.js","search.js","anspress.js","localize.js"]
Done.
*Gruntfile.js
// load config ##
grunt.registerTask(
'config'
, function() {
modules = grunt.file.readJSON('module.json')
grunt.log.write(JSON.stringify( modules.js ) );
}
);
Any ideas of pointers? Thanks!
The answer, was pretty simple - to include full paths to each "file" in the JSON, then Grunt parsed it withuot problems.

env variable in JSON file in public folder of CRA

I have this config.json file located in my public folder, in which I need to put some params different in development and in production modes. I fetch it when my app loads (fetch('config.json').then()).
Is there a way that my config.json file looks like that :
{
"url": "%REACT_APP_URL%"
}
Of course, the code above doesn't work : is there another solution ?
If you are using create-react-app, you don't need to use a config file. Simple create a .env file in the root directory and add your environment variables:
URL=REACT_APP_URL
In your app, simple do something like
const url = process.env.REACT_APP_URL
Check out my post https://medium.com/#selom/nice-article-a446406f4447

How to deploy a raw JSON file that Webpack 4 treats as a split module?

I don't think this is an uncommon problem, but it seems like the keywords turn up many false positives. I've tried searching for "webpack dynamic configuration file", "webpack runtime load JSON file", and more. I see many results for configuring Webpack dynamically, but not many for configuring a bundled app dynamically.
I want to have a configuration file that sits in my deployment as raw JSON, i.e. no Webpack runtime or module boilerplate. Just a valid JSON file.
I want to "import" that JSON configuration in my code as I would as if it were a module, i.e. like this:
import config from './config.json'
I want Webpack to omit the JSON file from the bundle, but insert any necessary code to asynchronously request and inject the config.json waiting on the server.
I want Webpack to ignore whether ./config.json exists at build time, and to just optimistically assume it will be in the right place at runtime.
I'd love if I could specify that './config.json' is a module alias, and for Webpack to copy the aliased file to the correct location (with name config.json) in the build directory.
This will give me a raw JSON file in my deployment that my site administrator can edit without running Webpack. It lets me as a developer code as if config.json is a regular module. How can I do this? I've seen suggestions to use
externals: {
'./config.json': "require('./config.prod.json')",
},
but that won't work in the browser, where require does not exist.
I've tried this configuration with no luck. The JSON is still inlined into the bundle:
resolve: {
alias: {
'./config.json': path.resolve(__dirname, 'src/config.prod.json')
}
},
optimization: {
splitChunks: {
cacheGroups: {
config: {
test: './config.json',
chunks: 'all',
name: 'config',
priority: 100
}
}
}
}
I am using Webpack 4.
In short, you can't use
import config from './config.json'
At least not if this should run in the browser.
webpack externals would make this possible for a nodejs application.
What you really want is a normal http call.
Just get the config.json file with something like fetch.
fetch('url/config.json')
You can use copy-webpack-plugin to put the config in the correct place when webpack compiles (but do you want that if there are changes directly to this file on the server)

Google Cloud Deployment Manager: Passing variables into templates

I'm using Google Cloud Deployment and I am trying to get external input into my template. Namely, I want to set a metadata variable on my instance (when creating the instance) but provide this value on execution.
I've tried:
gcloud deployment-manager deployments create test-api-backend --config test-api-backend.yaml --properties 'my_value=hello'
Which fails (The properties flag should only be used when passing in a template as your config file.)
I've tried:
my_value=hello gcloud deployment-manager deployments create test-api-backend --config test-api-backend.yaml
And use {{env['my_value']}} but the value isn't picked up.
I guess I could add the property in a .jinja file and re-write this file before I run everything, but it feels like a hack. That, or my idea of passing a variable from shell into Deploy Manager is a hack. I'm honestly not sure.
As the error message indicates, the command line properties can only be used with a template. They are essentially meant to replace the config yaml file.
The easiest thing to do is to just rename your yaml file to a .py or .jinja file. Then use that template as the file in the gcloud command instead of the yaml file.
In that new template file, add any defaults you would like if you don't pass them in on the command line.
For python, something like:
if 'myparam' in context.properties:
valuetouse = context.properities['myparam']
else:
valuetouse = mydefaultvalue
If the template uses another template then you'll also need to create a schema file for the new, top level template so you can do the imports there instead of the yaml file.
See the schema file in this github example.
https://github.com/GoogleCloudPlatform/deploymentmanager-samples/blob/master/examples/v2/igm-updater/ha-service.py.schema
If you want, you can ignore all the properties and just do the imports section.