Created
June 7, 2016 10:02
-
-
Save akerouanton/7d06eda2c640f4fd17badc5b3d7828ac to your computer and use it in GitHub Desktop.
Cloudformation, ansible, SSH bastion & rsync
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
/** Should go into roles/your_playbook/files/bastion.json */ | |
"AWSTemplateFormatVersion": "2010-09-09", | |
"Resources": { | |
"BastionInstance": { | |
"Type": "AWS::EC2::Instance", | |
"Properties": { | |
"AvailabilityZone": "eu-central-1a", | |
"ImageId": "ami-ccc021a3", | |
"InstanceType": "t2.nano", | |
"KeyName": {"Ref": "KeyName"}, | |
"NetworkInterfaces": [ | |
{ | |
"AssociatePublicIpAddress": true, | |
"DeviceIndex": 0, | |
"GroupSet": [{"Ref": "BastionSecurityGroup"}], | |
"SubnetId": {"Ref": "Subnet"} | |
} | |
], | |
"SourceDestCheck": true, | |
"Tags": [ | |
{"Key": "EnvironmentTag", "Value": {"Ref": "EnvironmentTag"}} | |
], | |
"UserData": {"Fn::Base64": {"Fn::Join": ["", [ | |
"#!/bin/bash -xe\n", | |
"echo '\nAllowAgentForwarding yes\n' >> /etc/ssh/sshd_config\n", | |
"systemctl restart ssh" | |
]]}} | |
} | |
}, | |
"BastionSecurityGroup": { | |
"Type": "AWS::EC2::SecurityGroup", | |
"Properties": { | |
"GroupDescription": "Security group for bastion instances", | |
"VpcId": {"Ref": "VpcId"}, | |
"SecurityGroupIngress": [ | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": 22, | |
"ToPort": 22, | |
"CidrIp": "0.0.0.0/0" | |
} | |
], | |
"SecurityGroupEgress": [ | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": 22, | |
"ToPort": 22, | |
"CidrIp": {"Ref": "VpcCidr"} | |
}, | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": 53, | |
"ToPort": 53, | |
"CidrIp": "0.0.0.0/0" | |
} | |
] | |
} | |
} | |
}, | |
"Parameters": { | |
"KeyName": { | |
"Type": "AWS::EC2::KeyPair::KeyName" | |
}, | |
"Subnet": { | |
"Type": "AWS::EC2::Subnet::Id" | |
}, | |
"VpcId": { | |
"Type": "AWS::EC2::VPC::Id" | |
}, | |
"VpcCidr": { | |
"Type": "String" | |
} | |
}, | |
"Outputs": { | |
"BastionInstance": { | |
"Value": {"Fn::GetAtt": ["BastionInstance", "PublicIp"]} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
# Should go into roles/your_playbook/tasks/main.yml | |
- name: validate cloudformation template for bastion stack | |
shell: aws cloudformation validate-template --template-body file://{{ playbook_dir }}/roles/your_playbook/files/bastion.json | |
always_run: yes | |
- name: start/update bastion stack from cloudformation template | |
cloudformation: | |
stack_name: "bastion" | |
aws_region: "{{ region }}" | |
state: present | |
disable_rollback: "{{ disable_rollback }}" | |
template: roles/your_playbook/files/bastion.json | |
template_parameters: | |
KeyName: "{{ user_ssh_key_pair }}" | |
Subnet: "{{ networking_stack.stack_outputs.PublicSubnet }}" | |
VpcId: "{{ networking_stack.stack_outputs.VPC }}" | |
VpcCidr: "{{ vpc_cidr }}" | |
DebugMode: "{{ ansible_debug|default(false)|string }}" | |
ignore_errors: yes | |
register: bastion_stack | |
when: not ansible_check_mode | |
- name: show bastion stack outputs | |
debug: var=bastion_stack.stack_outputs | |
when: ansible_debug|default(false) | |
- name: Create a local ssh_config file for accessing private instances | |
template: | |
src: ssh_config.j2 | |
dest: /tmp/ssh_config | |
when: not ansible_check_mode and not bastion_stack|failed and ansible_debug|default(false) | |
- name: delete failed bastion stack | |
cloudformation: | |
stack_name: "bastion" | |
aws_region: "{{ region }}" | |
state: absent | |
when: bastion_stack|failed and delete_on_failure | |
- name: wait for newly created bastion host to become ready | |
wait_for: | |
host: "{{ bastion_stack.stack_outputs.BastionInstance }}" | |
port: 22 | |
when: not ansible_check_mode | |
- name: copy blabla.sh through an SSH Bastion | |
synchronize: | |
src: "/tmp/blabla.sh" | |
dest: "/usr/src/app" | |
rsync_opts: "-e 'ssh -F /tmp/ssh_config'" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Should go into roles/your_playbook/templates/ssh_config.j2 | |
Host bastion.your_domain | |
Hostname {{ bastion_stack.stack_outputs.BastionInstance }} | |
Host {{ bastion_stack.stack_outputs.BastionInstance }} | |
User admin | |
ForwardAgent yes | |
ControlMaster auto | |
ControlPath ~/.ssh/ansible-%r@%h:%p | |
ControlPersist 5m | |
StrictHostKeyChecking no | |
UserKnownHostsFile /dev/null | |
Host 10.0.2.* | |
User admin | |
ProxyCommand ssh -F /tmp/ssh_config -W %h:%p admin@{{ bastion_stack.stack_outputs.BastionInstance }} | |
StrictHostKeyChecking no | |
UserKnownHostsFile /dev/null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment