0

问题:我正在尝试将动态创建的 python 脚本传递给使用 terraform 创建的 AWS launch_config。该脚本出现在实例的用户数据中,但不执行。我不确定为什么我阅读的所有关于通过用户数据传递脚本的指南都说这应该有效。

我知道脚本会显示,因为我可以 curl aws 用户数据并且它会在那里,但它从未执行过。

我错过了什么?

动态创建的python:

user_data_ins = ('''export CLOUD_ENVIRONMENT=%s\n
                    export CLOUD_MONITOR_BUCKET=%s\n
                    export CLOUD_APP=%s\n
                    export CLOUD_STACK=%s\n
                    export CLOUD_CLUSTER=%s\n
                    export CLOUD_AUTO_SCALE_GROUP=%s\n
                    export CLOUD_LAUNCH_CONFIG=%s\n
                    export EC2_REGION=%s\n
                    export CLOUD_DEV_PHASE=%s\n
                    export CLOUD_REVISION=%s\n
                    export CLOUD_DOMAIN=%s\n
                    export SG_GROUP=%s\n''' % (cloud_environment,
                                                cluster_monitor_bucket,
                                                cluster_name,
                                                cloud_stack,
                                                cloud_cluster,
                                                cloud_auto_scale_group,
                                                cloud_launch_config,
                                                provider_region,
                                                cloud_dev_phase,
                                                cloud_revision,
                                                cloud_domain,
                                                export_env_sg_name))



user_data_ins = ('''
#!/usr/bin/env python

import os
import subprocess
import time
import uuid


def shell_command_execute(command):
    p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
    (output, err) = p.communicate()
    print output
    return output

repo = "%s"
playbook = "%s"


echo_bash_profile = "echo " + %s + " >> ~/.bash_profile"
shell_command_execute(echo_bash_profile)

var_user_data = "%s"

for varb in var_user_data.split('|'):
    echo_bash_profile_passed = "echo " + varb  + " >> ~/.bash_profile"
    shell_command_execute(echo_bash_profile_passed)

command = 'git clone ' + repo
shell_command_execute(command)

folder = repo.split('/')[4].replace('.git','')
#https://github.com/zukeru/vision_provis.git
execute_playbook = ('ansible-playbook -i "localhost," -c local' +  '/' + os.path.dirname(os.path.realpath(__file__)) + '/' + folder + '/' + playbook >> ansible.log')
print execute_playbook
shell_command_execute(execute_playbook)
''' % (str(repo), str(playbook),str(user_data_ins), str(in_user_data)))

text_file = open("user-data.py", "wa")
text_file.write(user_data_ins)    
text_file.close()    
lc_user_data = '${file("%s/user-data.py")}' %wd

整个脚本:

import argparse
import subprocess
import sys
import boto.ec2
import random
import multiprocessing
import time
import collections
import os
import uuid
import base64

parser = argparse.ArgumentParser()    
parser.add_argument('--secret_key', help='', required=False)
parser.add_argument('--wd', help='', required=False)
parser.add_argument('--access_key', help='', required=False)
parser.add_argument('--provider-region', help='', required=False)
parser.add_argument('--autoscale_group', help='', required=False)
parser.add_argument('--min_size', help='', required=False)
parser.add_argument('--max_size', help='', required=False)
parser.add_argument('--asg_name', help='', required=False)
parser.add_argument('--azs', help='', required=False)
parser.add_argument('--env', help='', required=False)
parser.add_argument('--desired_size', help='', required=False)
parser.add_argument('--force_delete', help='', required=False)
parser.add_argument('--hc_type', help='', required=False)
parser.add_argument('--hc_period', help='', required=False)
parser.add_argument('--lc_name', help='', required=False)
parser.add_argument('--lc_image_id', help='', required=False)
parser.add_argument('--lc_instance_type', help='', required=False)
parser.add_argument('--lc_iam_instance_profile', help='', required=False)
parser.add_argument('--lc_key_name', help='', required=False)
parser.add_argument('--in_user_data', help='', required=False)
parser.add_argument('--lc_public_ip', help='', required=False)
parser.add_argument('--launch_config', help='', required=False)
parser.add_argument('--tags', help='', required=False)
parser.add_argument('--block_devices', help='', required=False)
parser.add_argument('--asg_vpc_ident', help='', required=False)
parser.add_argument('--cloud_stack', help='', required=False)
parser.add_argument('--cloud_environment', help='', required=False)
parser.add_argument('--cloud_domain', help='', required=False)
parser.add_argument('--cluster_monitor_bucket', help='', required=False)
parser.add_argument('--cloud_cluster', help='', required=False)
parser.add_argument('--cloud_auto_scale_group', help='', required=False)
parser.add_argument('--cloud_launch_config', help='', required=False)
parser.add_argument('--cloud_dev_phase', help='', required=False)
parser.add_argument('--cloud_revision', help='', required=False)
parser.add_argument('--role', help='', required=False)
parser.add_argument('--security_groups', help='', required=False)
parser.add_argument('--sg_tag', help='', required=False)
parser.add_argument('--vpc_id', help='', required=False)
parser.add_argument('--repo', help='', required=False)
parser.add_argument('--playbook', help='', required=False)
args = parser.parse_args()
#secret_key = os.environ.get('AWS_SECRET_KEY')
#access_key = os.environ.get('AWS_ACCESS_KEY')
sg_tag = args.sg_tag
secret_key = args.secret_key
access_key = args.access_key
vpc_id = args.vpc_id
provider_region = args.provider_region
security_groups = args.security_groups
cloud_stack = args.cloud_stack 
cloud_environment = args.cloud_environment
cloud_domain = args.cloud_domain
cluster_monitor_bucket = args.cluster_monitor_bucket
cloud_cluster =  args.cloud_cluster
cloud_auto_scale_group = args.cloud_auto_scale_group
cloud_launch_config = args.cloud_launch_config
cloud_dev_phase = args.cloud_dev_phase
cloud_revision = args.cloud_revision
role = args.role
env_name = args.env
#asg arguments
min_size = args.min_size
max_size = args.max_size
desired_size = args.desired_size
azs = args.azs
asg_name = args.asg_name
force_delete = args.force_delete
tags = args.tags
hc_type = args.hc_type
hc_period = args.hc_period
az_list = args.azs
vpc_zone_ident = args.asg_vpc_ident

#launch configuration values
lc_name = args.lc_name
lc_image_id = args.lc_image_id
lc_instance_type = args.lc_instance_type
lc_iam_instance_profile = args.lc_iam_instance_profile
lc_key_name = args.lc_key_name
in_user_data = args.in_user_data
lc_public_ip = args.lc_public_ip
block_devices = args.block_devices
security_group_name = []
wd = args.wd
playbook = args.playbook
repo = args.repo


def build_lc(lc_name, lc_name2, lc_image_id, lc_instance_type, lc_public_ip, lc_security_groups, lc_iam_instance_profile, lc_user_data, lc_key_name,block_device_mapping):
    launch_config_dict = collections.OrderedDict()
    if lc_name:
        launch_config_dict['lcname'] = lc_name
    if lc_name2:
        launch_config_dict['name'] = lc_name2
    if lc_image_id:
        launch_config_dict['image_id'] = lc_image_id
    if lc_instance_type:
        launch_config_dict['instance_type'] = lc_instance_type

    launch_config_dict['associate_public_ip_address'] = 'True'

    if lc_security_groups:
        launch_config_dict['security_groups'] = str(lc_security_groups).replace("'",'"')
    if lc_iam_instance_profile:
        launch_config_dict['iam_instance_profile'] = lc_iam_instance_profile
    if lc_user_data:
        launch_config_dict['user_data'] = lc_user_data
    if lc_key_name:
        launch_config_dict['key_name'] = lc_key_name
    if block_device_mapping:
        launch_config_dict['block_device'] = block_device_mapping


    lc_string = '\nresource "aws_launch_configuration" "%s" {\n' % launch_config_dict['lcname']

    for key, value in launch_config_dict.iteritems():
        if value != None:
            if key == 'lcname':
                continue
            if key != 'block_device':
                if key != 'security_groups':
                    lc_string = lc_string + '        %s="%s"\n' % (key, value)
                else:
                    lc_string = lc_string + '        %s=%s\n' % (key, value)
            else:
                lc_string = lc_string + '        %s\n' % (value)
    lc_string = lc_string + '\n    }'
    return lc_string

def build_tags(tags):
    built_tags = ''
    tags = tags.split(',')
    for tag in tags:
        if len(tag) > 5:
            values = tag.split(':')
            built_tags = built_tags + """
            tag {
                key = "%s"
                value = "%s"
                propagate_at_launch = %s
                }                                   
            """ % (values[0],values[1],values[2])
    return built_tags

def build_block_devices(block_devices):

    built_devices = ''
    block_devices = block_devices.split(',')
    for device in block_devices:
        if len(device) > 6:
            values = device.split(':')
            built_devices = built_devices + '''
                ebs_block_device{
                    device_name = "%s"
                    volume_type = "%s"
                    volume_size = %s
                    delete_on_termination = %s
                    iops = %s
                }
            ''' % (values[0].split('=')[1],values[1].split('=')[1],values[2].split('=')[1],values[3].split('=')[1],values[4].split('=')[1])
    return built_devices

def build_az_list(azs):
    az_list = []
    az_values = azs.split(',')
    for az in az_values:
        az_list.append('%s' % az)
    return az_list

def build_rules(rules):
    build_string = ''
    for rule in rules.split(':'):
        name = rule.split('=')[0]
        if len(rule) > 10:
            build_string = build_string + '''
                    %s {
                        from_port = %s
                        to_port = %s
                        protocol = "%s"
                        %s = %s
                        }
                        ''' % (name, 
                               rule.split('=')[1].split(';')[0].split('|')[1], 
                               rule.split('=')[1].split(';')[1].split('|')[1], 
                               rule.split('=')[1].split(';')[2].split('|')[1], 
                               rule.split('=')[1].split(';')[3].split('|')[0],
                               rule.split('=')[1].split(';')[3].split('|')[1])
    return build_string

def build_security_group(security_groups,vpc_id, cluster_name, sg_tag):
    security_group = ''
    flag = False
    for group in security_groups.split(','):
        if len(group) > 6:
            if 'name' in str(group):
                conn = boto.ec2.connect_to_region('us-west-2',aws_access_key_id=access_key, aws_secret_access_key=secret_key)
                rs = conn.get_all_security_groups()
                check_name = cluster_name.split('-')
                check_name = check_name[0]+'-'+check_name[1]+'-'+check_name[2]
                check_name = str(check_name)
                sg_length = len(rs)
                for index, item in enumerate(rs):
                    item_ret = str(item)
                    if check_name in item_ret:
                        name = item_ret.replace('SecurityGroup:', '')
                        name2 = item_ret.replace('SecurityGroup:', '')
                        security_group_name.append(str(item.id))
                        flag = True
                        break
                    else:
                        if not security_group_name and index == (sg_length - 1):
                            name = cluster_name
                            name2 = cluster_name
                            security_group_name.append("${aws_security_group.%s.id}" % name)
                            break

                description = group.split(':')[1].split('=')[1]
                rules = group.split('!')[1]
                rules = build_rules(rules)
                if vpc_id != '0':
                    security_group = security_group + '''
                    resource "aws_security_group" "%s" {
                        name = "%s"
                        vpc_id = "%s"
                        description = "%s"
                        %s
                    }''' % (name, name2,vpc_id, description, rules) 
                else:
                    security_group = security_group + '''
                    resource "aws_security_group" "%s" {
                        name = "%s"
                        description = "%s"
                        %s
                    }''' % (name, name2, description, rules)   
            else:
                break   
    return_list = (security_group,security_group_name, flag, name)    
    return return_list 

#Dynamically builds ASG, and won't include values  if they dont exist. Need to do errors when its required.
def build_asg(**kwargs):
    asg_string = '\nresource "aws_autoscaling_group" "%s" {\n' % kwargs['asgname']
    order_dict = collections.OrderedDict()
    if kwargs['name']:
        order_dict['name'] = kwargs['name']
    if kwargs['availability_zones']:
        order_dict['availability_zones'] = str(kwargs['availability_zones']).replace("'",'"')
    if kwargs['max_size']:
        order_dict['max_size'] = kwargs['max_size']
    else:
        order_dict['max_size'] = 1
    if kwargs['min_size']:
        order_dict['min_size'] = kwargs['min_size']
    else:
        order_dict['min_size'] = 1
    if kwargs['launch_configuration']:
        order_dict['launch_configuration'] = kwargs['launch_configuration']
    if kwargs['health_check_grace_period']:
        order_dict['health_check_grace_period'] = kwargs['health_check_grace_period']
    if kwargs['health_check_type']:
        order_dict['health_check_type'] = kwargs['health_check_type']
    if kwargs['desired_capacity']:
        order_dict['desired_capacity'] = kwargs['desired_capacity']
    if kwargs['force_delete']:
        order_dict['force_delete'] = kwargs['force_delete']
    if kwargs['vpc_zone_identifier']: 
        order_dict['vpc_zone_identifier'] = kwargs['vpc_zone_identifier']
    if kwargs['built_tags']: 
        order_dict['built_tags'] = kwargs['built_tags']

    for key, value in order_dict.iteritems():
        if value != None:
            if key == 'asgname':
                continue
            if key != 'built_tags':
                if key != 'force_delete' and key != 'health_check_grace_period' and key != 'min_size' and key != 'max_size' and key != 'desired_capacity' and key != 'availability_zones' and key != 'vpc_zone_identifier':
                    asg_string = asg_string + '        %s = "%s"\n' % (key, value)
                else:
                    asg_string = asg_string + '        %s = %s\n' % (key, value)
            else:
                asg_string = asg_string + '        %s\n' % (value)
    asg_string = asg_string + '\n    }'
    return asg_string

def get_a_uuid():
    r_uuid = base64.urlsafe_b64encode(uuid.uuid4().bytes)
    return r_uuid.replace('=', '')

uuid = str(get_a_uuid())
asg_name = sg_tag + '-' + asg_name + '-' + env_name + '-' + '-' + uuid[:8]
cluster_name = asg_name
security_groups = security_groups.replace(' ', '')
security_groups = build_security_group(security_groups,vpc_id, cluster_name, sg_tag)
security_group_name = security_groups[1]
export_env_sg_name = security_groups[3]
security_groups = security_groups[0]
security_flag = security_groups[2]


if security_flag == True:
    lc_security_groups = security_group_name[0]
    lc_security_groups = '["%s"],' % lc_security_groups
else:
    lc_security_groups = security_group_name

az_list = build_az_list(azs)
block_devices = block_devices.replace(' ', '')
block_device_mapping = build_block_devices(block_devices)

constant_tag = 'ClusterName:%s:true ' % cluster_name

if tags:
    built_tags = build_tags(tags)
else:
    built_tags = constant_tag


user_data_ins = ('''export CLOUD_ENVIRONMENT=%s\n
                    export CLOUD_MONITOR_BUCKET=%s\n
                    export CLOUD_APP=%s\n
                    export CLOUD_STACK=%s\n
                    export CLOUD_CLUSTER=%s\n
                    export CLOUD_AUTO_SCALE_GROUP=%s\n
                    export CLOUD_LAUNCH_CONFIG=%s\n
                    export EC2_REGION=%s\n
                    export CLOUD_DEV_PHASE=%s\n
                    export CLOUD_REVISION=%s\n
                    export CLOUD_DOMAIN=%s\n
                    export SG_GROUP=%s\n''' % (cloud_environment,
                                                cluster_monitor_bucket,
                                                cluster_name,
                                                cloud_stack,
                                                cloud_cluster,
                                                cloud_auto_scale_group,
                                                cloud_launch_config,
                                                provider_region,
                                                cloud_dev_phase,
                                                cloud_revision,
                                                cloud_domain,
                                                export_env_sg_name))



user_data_ins = ('''
#!/usr/bin/env python

import os
import subprocess
import time
import uuid


def shell_command_execute(command):
    p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
    (output, err) = p.communicate()
    print output
    return output

repo = "%s"
playbook = "%s"


echo_bash_profile = "echo " + %s + " >> ~/.bash_profile"
shell_command_execute(echo_bash_profile)

var_user_data = "%s"

for varb in var_user_data.split('|'):
    echo_bash_profile_passed = "echo " + varb  + " >> ~/.bash_profile"
    shell_command_execute(echo_bash_profile_passed)

command = 'git clone ' + repo
shell_command_execute(command)

folder = repo.split('/')[4].replace('.git','')
#https://github.com/zukeru/vision_provis.git
execute_playbook = ('ansible-playbook -i "localhost," -c local' +  '/' + os.path.dirname(os.path.realpath(__file__)) + '/' + folder + '/' + playbook >> ansible.log')
print execute_playbook
shell_command_execute(execute_playbook)
''' % (str(repo), str(playbook),str(user_data_ins), str(in_user_data)))

text_file = open("user-data.py", "wa")
text_file.write(user_data_ins)    
text_file.close()    
lc_user_data = '${file("%s/user-data.py")}' %wd

launch_config_variable = "${aws_launch_configuration.%s.id}" % cluster_name

launch_configuration = build_lc(cluster_name,cluster_name, lc_image_id, lc_instance_type, lc_public_ip, lc_security_groups, lc_iam_instance_profile, lc_user_data, lc_key_name,block_device_mapping)

autoscale_group = build_asg(built_tags = built_tags if built_tags else None,
                              asgname = asg_name, 
                              availability_zones = az_list, 
                              name = asg_name, 
                              max_size = max_size, 
                              min_size = min_size, 
                              launch_configuration = launch_config_variable, 
                              health_check_grace_period = hc_period if hc_period else None, 
                              health_check_type = hc_type if hc_type else None, 
                              desired_capacity = desired_size if desired_size else None, 
                              force_delete = force_delete if force_delete else None,
                              vpc_zone_identifier = vpc_zone_ident if vpc_zone_ident else None
                              )   

provider = """
        provider "aws" {
            access_key = "%s"
            secret_key = "%s"
            region = "%s"
        }
""" % (access_key, secret_key, provider_region)

text_file = open("Output.tf", "wa")
text_file.write(provider)

if security_flag == True:
    print 'nada'
else:
    text_file.write(security_groups)

text_file.write(launch_configuration)
text_file.write(autoscale_group)
text_file.close()

按照

我也对脚本进行了 base64 编码,EC2 实例加载了我的用户数据脚本,但没有运行它

但它仍然不起作用。

encoded = base64.b64encode(user_data_ins)
text_file.write(encoded)    
text_file.close()    
lc_user_data = '${file("%s/user-data.py")}' %wd

curl http://169.254.169.254/latest/user-data
CiMhL3Vzci9iaW4vZW52IHB5dGhvbgoKaW1wb3J0IG9zCmltcG9ydCBzdWJwcm9jZXNzCmltcG9ydCB0aW1lCmltcG9ydCB1dWlkCgoKZGVmIHNoZWxsX2NvbW1hbmRfZXhlY3V0ZShjb21tYW5kKToKICAgIHAgPSBzdWJwcm9jZXNzLlBvcGVuKGNvbW1hbmQsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHNoZWxsPVRydWUpCiAgICAob3V0cHV0LCBlcnIpID0gcC5jb21tdW5pY2F0ZSgpCiAgICBwcmludCBvdXRwdXQKICAgIHJldHVybiBvdXRwdXQKCnJlcG8gPSAiaHR0cHM6Ly9naXRodWIuY29tL3p1a2VydS92aXNpb25fcHJvdmlzLmdpdCIKcGxheWJvb2sgPSAic3Rvcm0ueW1sIgoKCmVjaG9fYmFzaF9wcm9maWxlID0gImVjaG8gIiArIGV4cG9ydCBDTE9VRF9FTlZJUk9OTUVOVD1pbnRlZ3JhdGlvbgoKICAgICAgICAgICAgICAgICAgICBleHBvcnQgQ0xPVURfTU9OSVR
PUl9CVUNLRVQ9MAoKICAgICAgICAgICAgICAgICAgICBleHBvcnQgQ0xPVURfQVBQPUVTLXRlc3Qtc3Rvcm0tZGVwbG95LURFVi0tT0ZETGVoYWEKCiAgICAgICAgICAgICAgICAgICAgZXhwb3J0IENMT1VEX1NUQUNLPWluZnJhCgogICAgICAgICAgICAgICAgICAgIGV4cG9ydCBDTE9VRF9DTFVTVEVSPTAKCiAgICAgICAgICAgICAgICAgICAgZXhwb3J0IENMT1VEX0FVVE9fU0NBTEVfR1JPVVA9MAoKICAgICAgICAgICAgICAgICAgICBleHBvcnQgQ0xPVURfTEFVTkNIX0NPTkZJRz0wCgogICAgICAgICAgICAgICAgICAgIGV4cG9ydCBFQzJfUkVHSU9OPXVzLXdlc3QtMgoKICAgICAgICAgICAgICAgICAgICBleHBvcnQgQ0xPVURfREVWX1BIQVNFPTAKCiAgICAgICAgICAgICAgICAgICAgZXhwb3J0IENMT1VEX1JFVklTSU9OPTAKCiAgICAgICAgICAgICAgICAgICAgZXhwb3J0IENMT1VEX0RPTUFJTj0wCgogICAgICAgICAgICAgICAgICAgIGV4cG9ydCBTR19HUk9VUD1FUy10ZXN0LXN0b3JtLWRlcGxveS1ERVYtLU9GRExlaGFhCiArICIgPj4gfi8uYmFzaF9wcm9maWxlIgpzaGVsbF9jb21tYW5kX2V4ZWN1dGUoZWNob19iYXNoX3Byb2ZpbGUpCgp2YXJfdXNlcl9kYXRhID0gImV4cG9ydCBTSEFSRFMgPSAzIgoKZm9yIHZhcmIgaW4gdmFyX3VzZXJfZGF0YS5zcGxpdCgnfCcpOgogICAgZWNob19iYXNoX3Byb2ZpbGVfcGFzc2VkID0gImVjaG8gIiArIHZhcmIgICsgIiA+PiB+Ly5iYXNoX3Byb2ZpbGUiCiAgICBzaGVsbF9jb21tYW5kX2V4ZWN1dGUoZWNob19iYXNoX3Byb2ZpbGVfcGFzc2VkKQoKY29tbWFuZCA9ICdnaXQgY2xvbmUgJyArIHJlcG8Kc2hlbGxfY29tbWFuZF9leGVjdXRlKGNvbW1hbmQpCgpmb2xkZXIgPSByZXBvLnNwbGl0KCcvJylbNF0ucmVwbGFjZSgnLmdpdCcsJycpCiNodHRwczovL2dpdGh1Yi5jb20venVrZXJ1L3Zpc2lvbl9wcm92aXMuZ2l0CmV4ZWN1dGVfcGxheWJvb2sgPSAoJ2Fuc2libGUtcGxheWJvb2sgLWkgImxvY2FsaG9zdCwiIC1jIGxvY2FsJyArICAnLycgKyBvcy5wYXRoLmRpcm5hbWUob3MucGF0aC5yZWFscGF0aChfX2ZpbGVfXykpICsgJy8nICsgZm9sZGVyICsgJy8nICsgcGxheWJvb2sgPj4gYW5zaWJsZS5sb2cnKQpwcmludCBleGVjdXRlX3BsYXlib29rCnNoZWxsX2NvbW1hbmRfZXhlY3V0ZShleGVjdXRlX3BsYXlib29rKQo=
4

0 回答 0