Open luckyraul opened 4 years ago
So the setting you want for each target's proxyjump
ssh config is in a different resource? Is that static information you could set at a group level?
groups:
- name: xxx_lb
targets:
- _plugin: terraform
dir: ../xxx
resource_type: aws_instance.lb
target_mapping:
uri: public_ip
- name: xxx_node
targets:
- _plugin: terraform
dir: ../xxx
resource_type: aws_instance.node
target_mapping:
uri: private_ip
proxyjump: ???
I need to set jumphost from xxx_lb public_ip
Will the value you need for xxx_node
from the aws_instance.lb
resource be the same for all xxx_node
targets? I'm thinking if we added functionality to just look up a single value from a resource from a statefile that would help there. So for example:
groups:
- name: xxx_lb
targets:
- _plugin: terraform
dir: ../xxx
resource_type: aws_instance.lb
target_mapping:
uri: public_ip
- name: xxx_node
targets:
- _plugin: terraform
dir: ../xxx
resource_type: aws_instance.node
target_mapping:
uri: private_ip
config:
transport: ssh
ssh:
proxyjump:
_plugin: task
task: terraform::lookup
dir: ../xxx
resource: aws_instance.lb.path.to.value
Yes. Also I am thinking about terraform outputs. Can we use terraform outputs ?
"outputs": {
"public_ips": {
"value": [
[
"xxx.xx.x.x"
]
],
The output task is a good start to a generic look the value for a single resource
task, but wont quite work as a plugin task because the task would need to have the data under a value
key.
I'm wondering how common it will be to need a "static" value from a statefile, the exising plugin assumes you want to iterate over all the instances of a certain resource type (which breaks down if you were trying to incorporate data from another group of resources). If there are some common use cases for needing "static" values from a statefile i think we could fairly easily do that.
As far as a workaround for now, If you are willing to wrap whatever you need to do in an "inventory helper" plan you could use the xisting output task in combination with the example inventoryfile from above.. I'm thinking something roughly like:
plan inventory_helper(){
$xxx_nodes = get_targets('xxx_node')
$proxyjump_data = run_task('terraform::output', 'localhost', dir => 'path/to/dir')
$xxx_nodes.each |$target| {
$target.set_config(['ssh','proxyjump', $proxyjump_data[0].value['outputs']['public_ips']['value'][0][0]
}
# now $xxx_nodes should have config you need
}
terraform output is also in the statefile
I added an example that sketches out my idea for this (https://github.com/puppetlabs/puppetlabs-terraform/pull/20). I'll see what the Bolt team thinks about it this week.
(for example an inventoryfile utilizing the new task plugin might look something like the following for your case)
groups:
- name: ssh_targets
targets:
_plugin: terraform
dir: .
resource_type: docker_container.sshd
target_mapping:
name: name
config:
ssh:
host: ports.0.ip
port: ports.0.external
config:
transport: ssh
ssh:
proxyjump:
_plugin: task
task: terraform::tfstate_lookup
parameters:
dir: .
resource_type: docker_container.sshd
attribute_path: 0.ports.0.ip
user: root
password: root
host-key-check: false
Will it works with facts?
Remember that the plugin execution operates on a "localhost" target, so the only facts that would be available are those of the bolt runner.
I mean, to add custom facts to a inventory group or a node from the terraform state variable
Yeah, plugins can be used there: for example:
targets:
- name: foo
facts:
foo:
_plugin: env_var
var: MY_FACT
cas@cas-ThinkPad-T460p:~/working_dir/bolt$ MY_FACT=bar bolt inventory show -t foo --detail
{
"targets": [
{
"name": "foo",
"uri": null,
"alias": [
],
"config": {
"transport": "ssh",
"ssh": {
"cleanup": true,
"connect-timeout": 10,
"disconnect-timeout": 5,
"load-config": true,
"login-shell": "bash",
"tty": false,
"host-key-check": false
}
},
"vars": {
},
"features": [
],
"facts": {
"foo": "bar"
},
"plugin_hooks": {
"puppet_library": {
"plugin": "puppet_agent",
"stop_service": true
}
},
"groups": [
"all"
]
}
]
}
1 target
Any Updates about Release ?
@luckyraul Yes, it works for facts like any other target map:
---
groups:
- name: docker
targets:
- _plugin: terraform
resource_type: docker_container.*
target_mapping:
uri: network_data.0.ip_address
name: name
facts:
docker:
id: id
image: image
domain: domainname
network: network_data.0
In terraform state there is one object with a public IP, all others have privates, I guess I can use mapping to set proxyjump to a target, but how can set it from another resource? Should I parse terraform output ?