Terraform: How Do I Setup a Resource Based on Configuration - conditional-statements

So here is what I want as a module in Pseudo Code:
IF UseCustom, Create AWS Launch Config With One Custom EBS Device and One Generic EBS Device
ELSE Create AWS Launch Config With One Generic EBS Device
I am aware that I can use the 'count' function within a resource to decide whether it is created or not... So I currently have:
resource aws_launch_configuration "basic_launch_config" {
count = var.boolean ? 0 : 1
blah
}
resource aws_launch_configuration "custom_launch_config" {
count = var.boolean ? 1 : 0
blah
blah
}
Which is great, now it creates the right Launch configuration based on my 'boolean' variable... But in order to then create the AutoScalingGroup using that Launch Configuration, I need the Launch Configuration Name. I know what you're thinking, just output it and grab it, you moron! Well of course I'm outputting it:
output "name" {
description = "The Name of the Default Launch Configuration"
value = aws_launch_configuration.basic_launch_config.*.name
}
output "name" {
description = "The Name of the Custom Launch Configuration"
value = aws_launch_configuration.custom_launch_config.*.name
}
But how the heck do I know from the higher area that I'm calling the module that creates the Launch Configuration and Then the Auto Scaling Group which output to use for passing into the ASG???
Is there a different way to grab the value I want that I'm overlooking? I'm new to Terraform and the whole no real conditional thing is really throwing me for a loop.

Terraform: How to conditionally assign an EBS volume to an ECS Cluster
This seemed to be the cleanest way I could find, using a ternary operator:
output "name {
description = "The Name of the Launch Configuration"
value = "${(var.booleanVar) == 0 ? aws_launch_configuration.default_launch_config.*.name : aws_launch_configuration.custom_launch_config.*.name}
}
Let me know if there is a better way!

You can use the same variable you used to decide which resource to enable to select the appropriate result:
output "name" {
value = var.boolean ? aws_launch_configuration.custom_launch_config[0].name : aws_launch_configuration.basic_launch_config[0].name
}
Another option, which is a little more terse but arguably also a little less clear to a future reader, is to exploit the fact that you will always have one list of zero elements and one list with one elements, like this:
output "name" {
value = concat(
aws_launch_configuration.basic_launch_config[*].name,
aws_launch_configuration.custom_launch_config[*].name,
)[0]
}
Concatenating these two lists will always produce a single-item list due to how the count expressions are written, and so we can use [0] to take that single item and return it.

Related

Azure Workbook parameter for resource and resource group

I've been defeated by Kusto on what I thought to be a simple query...
I'm making my first workbook and playing with parameters. I can list and select a Resource Group, but I can't make the following parameter (Virtual Machines) populate with the VMs when more than one Resource Group is selected. The ResourceGroup passes a comma delineated string of the group names as a property resourcegroup just fine. I cannot figure out how to translate that string into a usable where-statement. My query works just fine when I manually string several Resource Groups together so I assume I'm getting burned by my understanding of let and arrays in Kusto. If there is a better way of doing what I'm trying to do, please let me know.
//This will work so long as 1 Resource Group is passed from the previous parameter
resources
| where resourceGroup in ('{ResourceGroup:resourcegroup}') and type =~ microsoft.compute/virtualmachines'
| project value = id , label = name
I've figured out I can get a proper array with split('{ResourceGroup:resourcegroup}',","), but, again, I haven't been able to marry up that object with a where-statement.
Any help is much appreciated!
in https://github.com/microsoft/Application-Insights-Workbooks/blob/master/Documentation/Parameters/DropDown.md#special-casing-all
NORMALLY there is a way to do this:
let resourceGroups = dynamic([{ResourceGroup:resourcegroup}]);// turns even an empty string into a valid array
resources
| where (array_length(resourceGroups)==0 // allows 0 length array to be "all"
or resourceGroup in (resourceGroups)) // or filters to only those in the set
and type =~ microsoft.compute/virtualmachines'
| project value = id , label = name
however, i don't think Azure Resource Graph allows using let this way?
if you get an error that let isn't allowed, you'll have to do that dynamic thing inline a couple times instead:
resources
| where (array_length(dynamic([{ResourceGroup:resourcegroup}]))==0 // allows 0 length array to be "all"
or resourceGroup in (dynamic([{ResourceGroup:resourcegroup}]))) // or filters to only those in the set
and type =~ microsoft.compute/virtualmachines'
| project value = id , label = name

How to check if a Gun unordered list is empty?

Given the following, how would one go about determining if the machines list is empty in order to add a machine?
let gun = new Gun();
let machines = gun.get('machines');
How do I check if the machines list is empty?
This from Mark Nadal:
// machineId and location defined elsewhere
machines.val(table => {
if (Gun.obj.empty(table, '_') {
// table is empty so we can add something to it
let machine = gun.get('machine/' + machineId);
machine.put({machineId, location}};
machines.set(machine);
} else {
// table is not empty
})
table is a data node that has all the row pointers in it (not the actual sub-objects)
so if table has 0 items on it, then it is empty! Or if table is null or undefined
HOWEVER, gun has its {_: {...}} meta data it includes on every node, so you need to ignore that.
Gun.obj.empty({}) tests if an object is empty (you can use lodash or something else), the second parameter tells it to IGNORE a key, like in this case '_'. So it will still say that yes it is empty if it has 0 properties other than the metadata property.

Default values for query parameters

Please forgive me if my question does not make sense.
What im trying to do is to inject in values for query parameters
GET1 File
Scenario:
Given path 'search'
And param filter[id] = id (default value or variable from another feature file)
POST1 File
Scenario:
def newid = new id made by a post call
def checkid = read call(GET1) {id : newid}
like if one of my feature files creates a new id then i want to do a get call with the above scenario. therefore i need a parameter there which takes in the new id.
On the other hand if i do not have an id newly created or the test creating it is not part of the suite. i want to still be able to run the above mentioned scenario but this time it has a default value to it.
Instead of param use params. It is designed so that any keys with null values are ignored.
After the null is set on the first line below, you can make a call to another feature, and overwrite the value of criteria. If it still is null, no params will be set.
* def criteria = null
Given path 'search'
And params { filter: '#(criteria)' }
There are multiple other ways to do this, also refer to this set of examples for data-driven search params: dynamic-params.feature
The doc on conditional logic may also give you some ideas.

How to access a stored value in PHPUnit_Extensions_SeleniumTestCase

How can I store a value within Selenium-RC (through PHPUnit) and then retrieve/access it later using PHPUnit?
Suppose I run a command like the following in a test:
$this->storeExpression( "foo", "bar" );
If I understand the Selenium API documentation correctly, I could access this data using javascript{storedVars['foo']} using good 'ol fashioned Selenese. It should contain the value "bar".
My question is this: how can I access this javascript{storedVars['test']} expression (or, more generally, javascript{storedVars} in PHPUnit?
For example, here's a simple test I've run:
public function testStorage()
{
$this->open('http://www.google.com/'); // for example
$this->storeExpression( 'foo', 'bar' );
$foo = $this->getExpression('foo');
echo $foo;
}
The output of which is "foo" (among the other standard PHPUnit output), while I expect it should be "bar". It's just giving me back the name of the expression, not its value.
Can anyone with experience in this give me some guidance?
Good posts in this thread, but looks like no 100% working answer so far.
Based on the Selenium reference here
http://release.seleniumhq.org/selenium-core/1.0/reference.html#storedVars
It would seem the correct code syntax would be:
$this->storeExpression( 'bar', 'foo' );
$foo = $this->getExpression("\${foo}");
I haven't tested that exactly, but doing something similar with
$this->storeHtmlSource('srcTxt');
$val = $this->getExpression('\${srcTxt}');
print $val;
did the trick for me.
The PHPUnit Selenium Testcase driver actually understands storeExpression and getExpression; have a look at its source code. You can do
$this->storeExpression('foo', 'bar');
and
$this->getExpression('foo');
As Selenium Stores the expression result in second argument it stores value in "bar" and when u need to call it you should call the stored name to get the expression.
$this->storeExpression( 'foo', 'bar' );
$foo = $this->getExpression("bar");
May this helps you it worked for me.
EDIT :
$evaluated = $this->getEval("regex:3+3");
$expressed = $this->getExpression("regex:3+3");
The First Evaluated will give the evaluated output for expression
and the second will show the expressed output.
The secound is used to verify that the specified expression is genrated or not by the alert.

Can I pretty-print the DBIC_TRACE output in DBIx::Class?

Setting the DBIC_TRACE environment variable to true:
BEGIN { $ENV{DBIC_TRACE} = 1 }
generates very helpful output, especially showing the SQL query that is being executed, but the SQL query is all on one line.
Is there a way to push it through some kinda "sql tidy" routine to format it better, perhaps breaking it up over multiple lines? Failing that, could anyone give me a nudge into where in the code I'd need to hack to add such a hook? And what the best tool is to accept a badly formatted SQL query and push out a nicely formatted one?
"nice formatting" in this context simply means better than "all on one line". I'm not particularly fussed about specific styles of formatting queries
Thanks!
As of DBIx::Class 0.08124 it's built in.
Just set $ENV{DBIC_TRACE_PROFILE} to console or console_monochrome.
From the documentation of DBIx::Class::Storage
If DBIC_TRACE is set then trace information is produced (as when the
debug method is set). ...
debug Causes trace information to be emitted on the debugobj
object. (or STDERR if debugobj has not specifically been set).
debugobj Sets or retrieves the object used for metric collection.
Defaults to an instance of DBIx::Class::Storage::Statistics that is
compatible with the original method of using a coderef as a callback.
See the aforementioned Statistics class for more information.
In other words, you should set debugobj in that class to an object that subclasses DBIx::Class::Storage::Statistics. In your subclass, you can reformat the query the way you want it to be.
First, thanks for the pointers! Partial answer follows ....
What I've got so far ... first some scaffolding:
# Connect to our db through DBIx::Class
my $schema = My::Schema->connect('dbi:SQLite:/home/me/accounts.db');
# See also BEGIN { $ENV{DBIC_TRACE} = 1 }
$schema->storage->debug(1);
# Create an instance of our subclassed (see below)
# DBIx::Class::Storage::Statistics class
my $stats = My::DBIx::Class::Storage::Statistics->new();
# Set the debugobj object on our schema's storage
$schema->storage->debugobj($stats);
And the definition of My::DBIx::Class::Storage::Statistics being:
package My::DBIx::Class::Storage::Statistics;
use base qw<DBIx::Class::Storage::Statistics>;
use Data::Dumper qw<Dumper>;
use SQL::Statement;
use SQL::Parser;
sub query_start {
my ($self, $sql_query, #params) = #_;
print "The original sql query is\n$sql_query\n\n";
my $parser = SQL::Parser->new();
my $stmt = SQL::Statement->new($sql_query, $parser);
#printf "%s\n", $stmt->command;
print "The parameters for this query are:";
print Dumper \#params;
}
Which solves the problem about how to hook in to get the SQL query for me to "pretty-ify".
Then I run a query:
my $rs = $schema->resultset('SomeTable')->search(
{
'email' => $email,
'others.some_col' => 1,
},
{ join => 'others' }
);
$rs->count;
However SQL::Parser barfs on the SQL generated by DBIx::Class:
The original sql query is
SELECT COUNT( * ) FROM some_table me LEFT JOIN others other_table ON ( others.some_col_id = me.id ) WHERE ( others.some_col_id = ? AND email = ? )
SQL ERROR: Bad table or column name '(others' has chars not alphanumeric or underscore!
SQL ERROR: No equijoin condition in WHERE or ON clause
So ... is there a better parser than SQL::Parser for the job?