Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inopinatus/fa8d146d968515e6ccfc495a95cee1d7 to your computer and use it in GitHub Desktop.
Save inopinatus/fa8d146d968515e6ccfc495a95cee1d7 to your computer and use it in GitHub Desktop.
OpWorks Stacks managed instance self-update to have IPv6 address.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DescribeNetworkInterfaces",
"ec2:AssignIpv6Addresses"
],
"Resource": "*"
}
]
}
# Copyright 2019, Joshua Goodall. MIT license.
require 'aws-sdk-ec2'
class EC2InterfaceV6Setup
attr_reader :instance_id, :client, :logger
def initialize(instance_id, aws_region, logger = Chef::Log)
@instance_id = instance_id
@client = Aws::EC2::Client.new(region: aws_region)
@logger = logger
end
def run
interfaces.each do |interface|
if interface.ipv_6_addresses.empty?
logger.info "adding new IPv6 address to interface #{interface.network_interface_id}"
response = assign_ipv6_address(interface)
logger.info "result of adding IPv6 address: interface #{response.network_interface_id} now has IPv6 address(es): #{response.assigned_ipv_6_addresses.join(', ')}"
else
logger.info "interface #{interface.network_interface_id} already has IPv6 address(es): #{interface.ipv_6_addresses.map(&:ipv_6_address).join(', ')}"
end
end
end
def assign_ipv6_address(interface)
client.assign_ipv_6_addresses({
ipv_6_address_count: 1,
network_interface_id: interface.network_interface_id
})
end
def interfaces
client.describe_network_interfaces(filters: filters).network_interfaces
end
def filters
[
{name: 'attachment.instance-id', values: [instance_id]},
{name: 'attachment.device-index', values: ["0"]}
]
end
end
# Cookbook Name:: inopinatus
# Recipe:: configure
#
# Copyright 2019, Joshua Goodall. MIT license.
include_recipe 'inopinatus::ipv6'
# ...other lines...
# Cookbook Name:: inopinatus
# Recipe:: ipv6
#
# Copyright 2019, Joshua Goodall. MIT license.
ec2_instance_id = search("aws_opsworks_instance", "self:true").first['ec2_instance_id']
region = search("aws_opsworks_stack").first['region']
v6setup = EC2InterfaceV6Setup.new(ec2_instance_id, region)
v6setup.run
@inopinatus
Copy link
Author

inopinatus commented Jun 27, 2019

This gist allows instances launched by OpsWorks Stacks to update themselves such that they're assigned an IPv6 address, which currently doesn't happen even if the VPC is configured as such. The address itself will flow through within seconds/minutes via DHCP refresh.

Beforehand:

  • Ensure that IPv6 is fully and correctly configured for the VPC subnets, route tables, security groups and ACLs in question.
  • Verify that the IAM policy is right for you.

Steps:

  • Attach IAM policy to the OpsWorks ec2 instance role e.g. as an inline policy.
  • Place Ruby files in a custom cookbook (subsitute '/' for '::' in filenames).
  • Ensure the packaged custom cookbook depends on/bundles the aws cookbook from Chef Supermarket.
  • Ensure custom inopinatus::configure recipe is included the Configure step of relevant OpsWorks layer.

Tested with Ubuntu 18.04LTS, but should work on any current OpsWorks-launched Linux type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment