While there are definite benefits to having a zero trust network, it’s also convenient to outsource all the certificate management.
First you need to create a cert with ACM, either by importing it, or letting them do it (managed renewal ftw!):
DomainName: !Ref 'DomainName'
That in hand, you can create the LB, Listener & Target Group:
- !Ref PublicSubnet1
- !Ref SecurityGroup
LoadBalancerArn: !Ref LoadBalancer
- Type: forward
TargetGroupArn: !Ref DefaultTargetGroup
- CertificateArn: !Ref Certificate
VpcId: !Ref Vpc
VpcId: !Ref Vpc
GroupDescription: Enable HTTPS access for LB
- IpProtocol: tcp
Make sure you use a public subnet, or you won’t be able to reach the LB!
There’s some useful info available about using a jump host with Ansible, and AWS dynamic inventory; but either the world has changed since those were written, or my scenario is slightly different.
I defined my inventory first:
- key: tags.Type
(that last bit is important, otherwise the ssh config won’t work). At this point you should be able to list (or graph) the instances you want to connect to:
$ ansible-inventory -i inventories/eu-west-2.aws_ec2.yml --list
Next you need some ssh config:
ProxyCommand ssh -W %h:%p firstname.lastname@example.org
I kept it pretty minimal. The IP mask needs to match whatever you used for the subnet(s) the instances are attached to (obvs). And the login may vary depending on the image you used, if you are using the defaults.
You can then use this config when running your playbook:
ANSIBLE_SSH_ARGS="-F lon_ssh_config" ansible AppServer -i inventories/eu-west-2.aws_ec2.yml -u admin -m ping
The IP address for the jump host is hard-coded in the ssh config, which isn’t ideal. We may use a DNS record, and update that instead, if it changes; but there doesn’t seem any easy way to either get that from the inventory, or update the cname automatically.
There are plenty of examples for creating an ASG using a CloudFormation template, but those I found all used a “launch configuration“.
According to the docs, using a launch template is the new hotness, so I foolishly assumed it would be simple to adapt one to the other.
Some time later, I had a working example:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber