Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/support passing ref to user data #724

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
17 changes: 17 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,23 @@ Duplicating a single instance sample would look like this

print(template.to_json())

UserData
========
You can pass in user data script to your launch config using ``from_file`` helper function under helpers/userdata.py file.
You can also use ``Ref`` method in the script file which will be translated into CloudFormation function.

Example:

.. code:: bash

#!/bin/bash -ex

/opt/aws/bin/cfn-init -v --stack "Ref('AWS::StackName')" \
--resource LaunchConfig \
--configsets ConfigCluster \
--region Ref('AWS::Region')


Community
=========

Expand Down
14 changes: 14 additions & 0 deletions tests/test_userdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ def test_char_escaping(self):
def test_nonexistant_file(self):
self.assertRaises(IOError, self.create_result, 'nonexistant.sh')

def test_if_ref_is_replaced(self):
result = self.create_result('ref_func.sh')

answer = self.create_answer([
'/opt/aws/bin/cfn-init -v --stack "',
{'Ref': 'AWS::StackName'},
'" \\\n',
' --resource LaunchConfig \\\n',
' --configsets ConfigCluster \\\n',
' --region ',
{'Ref': 'AWS::Region'},
'\n'])
self.assertEqual(result, answer)


if __name__ == '__main__':
unittest.main()
4 changes: 4 additions & 0 deletions tests/userdata_test_scripts/ref_func.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/opt/aws/bin/cfn-init -v --stack "Ref('AWS::StackName')" \
--resource LaunchConfig \
--configsets ConfigCluster \
--region Ref('AWS::Region')
23 changes: 21 additions & 2 deletions troposphere/helpers/userdata.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#!/usr/bin/python

from troposphere import Base64, Join
import re

from troposphere import Base64, Join, Ref

def from_file(filepath, delimiter='', blanklines=False):

def from_file(filepath, delimiter='', blanklines=False, searchref=True):
"""
Imports userdata from a file.
Also supports passing Troposphere Ref function

:type filepath: string
:param filepath
Expand All @@ -31,6 +34,22 @@ def from_file(filepath, delimiter='', blanklines=False):
if blanklines and line.strip('\n\r ') == '':
continue

if searchref:
pattern = r"""(?P<prefix>.*)
Ref\(\'(?P<reference>[a-zA-Z0-9\:]+)\'\)
(?P<suffix>.*[^\\*])"""
ref_pattern = re.compile(pattern, re.VERBOSE)

ref_ex = ref_pattern.match(line)

if ref_ex:
data.append(ref_ex.group('prefix'))
data.append(Ref(ref_ex.group('reference')))

if ref_ex.group('suffix'):
data.append(ref_ex.group('suffix'))
continue

data.append(line)
except IOError:
raise IOError('Error opening or reading file: {}'.format(filepath))
Expand Down