<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Bastion hosts
There are many reasons for using bastion hosts
Step1:  ssh_config
Instead of continuously passing options to ssh, we can use -F ssh_config and put configurations there.
Step2:  If we don't use it, we can turn off GSSApiAuthentication which attempts may slow down the connection.
Unsecure by design
Inhibit PKI authentication is insecure by design
Step3:  Exercise
Write the ssh-copy-id.yml playbook to install an ssh key to the bastion.
Bastion credentials are
Step4:  ansible.cfg and ssh_config
In the previous exercise, we used the [ssh_connection] stanza to configure ssh connections.
We can instead just set
[ssh_connection]
ssh_args = -F ssh_config
Write everything in ssh_config.
Connecting via bastion in ansible enforcing multiple references to ssh_config
Exercise
Uncomment the last lines of  ssh_config and try to use bastion for connecting to the other hosts
<ASSISTANT_TASK:>
Python Code:
cd /notebooks/exercise-06/
Explanation: Bastion hosts
There are many reasons for using bastion hosts:
security access eg in cloud environment
vpn eg via windows hosts
The latter case is quite boring as ansible doesn't support windows as a client platform.
A standard approach is:
have a ssh server or a proxy installed on the bastion
connecto the bastion to the remote network (eg. via vpn)
configure ssh options in ansible to connect thru the bastion
We'll do this via two configuration files:
a standard ssh_config where we put the passthru configuration
a simple ansible.cfg referencing ssh_config
This approach allows us:
to test the standard ssh connection thru the bastion without messing with ansible
keep ansible.cfg simple in case we want to reuse them from the intranet (Eg. without traversing the bastion)
End of explanation
!cat ssh_config
Explanation: ssh_config
Instead of continuously passing options to ssh, we can use -F ssh_config and put configurations there.
End of explanation
fmt=r'{{.NetworkSettings.IPAddress}}'
!docker  -H tcp://172.17.0.1:2375 inspect  ansible101_bastion_1 --format {fmt} # pass variables *before* commands ;)
Explanation: If we don't use it, we can turn off GSSApiAuthentication which attempts may slow down the connection.
Unsecure by design
Inhibit PKI authentication is insecure by design:
passwords will surely ends in cleartext files
people ends doing things like the following
```
the password is sent to the bastion via a
cleartext file.
Match Host 172.25.0.*
    ProxyCommand sshpass -f cleartext-bastion-password ssh -F config jump@bastion -W %h:%p 
```
Connect to the bastion
Test connectivity to the bastion. Check your host ips and modify  ssh_config  accordingly.
 Replace ALL bastion occurrencies, including the one below the BEWARE note
End of explanation
# Use this cell to create the pin file and then encrypt the vault
# Use this cell to test/run  the playbook. You can --limit the execution to the bastion host only.
!ssh -Fssh_config bastion hostname
Explanation: Exercise
Write the ssh-copy-id.yml playbook to install an ssh key to the bastion.
Bastion credentials are:
user: root
password root
Try to do it without watching the previous exercises:
modify the empty ansible.cfg
referencing a pin file 
passing [ssh_connection] arguments to avoid ssh key mismatches
pointing to the local inventory
store credentials in the encrypted vault.yml. 
provide an inventory file 
You can reuse the old id_ansible key or:
create a new one and adjust the reference in ssh_config 
Hint:
if you provide an IdentityFile, password authentication won't work on the bastion node;
you must copy ssh id file using password authentication and eventually clean up your known_host file
End of explanation
fmt=r'{{.NetworkSettings.IPAddress}}'
!docker  -H tcp://172.17.0.1:2375 inspect  ansible101_web_1 --format {fmt} # pass variables *before* commands ;)
!ssh -F ssh_config  root@172.17.0.4 ip -4 -o a  # get host ip
Explanation: ansible.cfg and ssh_config
In the previous exercise, we used the [ssh_connection] stanza to configure ssh connections.
We can instead just set
[ssh_connection]
ssh_args = -F ssh_config
Write everything in ssh_config.
Connecting via bastion in ansible enforcing multiple references to ssh_config
Exercise
Uncomment the last lines of  ssh_config and try to use bastion for connecting to the other hosts
End of explanation
<END_TASK>