diff --git a/inventory/host_vars/209.132.184.111 b/inventory/host_vars/209.132.184.111 new file mode 100644 index 0000000000..48de62649c --- /dev/null +++ b/inventory/host_vars/209.132.184.111 @@ -0,0 +1,11 @@ +--- +instance_type: m1.xlarge +image: emi-3F1C4010 +volumes:[ ] +keypair: admin +security_group: webserver +zone: fedoracloud +hostbase: jenkins-master- +public_ip: 209.132.184.111 +root_auth_users: [ pingou, skvidal ] +description: jenkins master instance diff --git a/inventory/inventory b/inventory/inventory index b997a8f225..8ca28d31b2 100644 --- a/inventory/inventory +++ b/inventory/inventory @@ -292,3 +292,7 @@ virthost12.phx2.fedoraproject.org virthost13.phx2.fedoraproject.org virthost-comm01.qa.fedoraproject.org + +[persistent-cloud] +209.132.184.111 +209.132.184.112 diff --git a/library/ec2_create b/library/ec2_create new file mode 100755 index 0000000000..e15ec6450b --- /dev/null +++ b/library/ec2_create @@ -0,0 +1,187 @@ +#!/usr/bin/python -tt +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +DOCUMENTATION = ''' +--- +module: ec2_create +short_description: create an instance in ec2, return instanceid +description: + - creates ec2 instances and optionally waits for it to be 'running' +version_added: "0.9" +options: + keypair: + description: + - keypair to use on the instance + required: true + default: null + aliases: [] + group: + description: + - security group to use on the instance + required: false + default: 'default' + aliases: [] + instance_type: + description: + - instance type to use for the instance + required: true + default: null + aliases: [] + image: + description: + - emi (or ami) to use for the instance + required: true + default: null + aliases: [] + kernel: + description: + - kernel eki to use for the instance + required: false + default: null + aliases: [] + ramdisk: + description: + - ramdisk eri to use for the instance + required: false + default: null + aliases: [] + wait: + description: + - wait for the instance to be in state 'running' before returning + required: False + default: False + aliases: [] + ec2_url: + description: + - url to use to connect to ec2 or your cloud + required: False + default: null + aliases: [] + ec2_secret_key: + description: + - ec2 secret key + required: False + default: null + aliases: [] + ec2_access_key: + description: + - ec2 access key + required: False + default: null + aliases: [] + +examples: + - code: "local_action: ec2_create keypair=admin instance_type=m1.large image=emi-40603AD1 wait=true group=webserver" + description: "Examples from Ansible Playbooks" + - code: +requirements: [ "euca2ools" ] +author: Seth Vidal + +''' + +import euca2ools.commands.euca.runinstances +import time + +def _run(cmd): + # returns (rc, stdout, stderr) from shell command + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, shell=True) + stdout, stderr = process.communicate() + return (process.returncode, stdout, stderr) + + +def main(): + module = AnsibleModule( + argument_spec = dict( + keypair = dict(required=True), + group = dict(default='default'), + instance_type = dict(aliases=['type']), + image = dict(required=True), + kernel = dict(), + #count = dict(default='1'), # maybe someday + ramdisk = dict(), + wait = dict(choices=BOOLEANS, default=False), + ec2_url = dict(aliases=['EC2_URL']), + ec2_secret_key = dict(aliases=['EC2_SECRET_KEY']), + ec2_access_key = dict(aliases=['EC2_ACCESS_KEY']), + ) + ) + + keypair = module.params.get('keypair') + group = module.params.get('group') + instance_type = module.params.get('instance_type') + image = module.params.get('image') + #count = module.params.get('count') + kernel = module.params.get('kernel') + ramdisk = module.params.get('ramdisk') + wait = module.params.get('wait') + ec2_url = module.params.get('ec2_url') + ec2_secret_key = module.params.get('ec2_secret_key') + ec2_access_key = module.params.get('ec2_access_key') + + if ec2_url: + os.environ['EC2_URL'] = ec2_url + if ec2_secret_key: + os.environ['EC2_SECRET_KEY'] = ec2_secret_key + if ec2_access_key: + os.environ['EC2_ACCESS_KEY'] = ec2_access_key + + + # yes I recognize how hacky this is - but it is easier than rewriting + # all the try/except's myself. + sys.argv.append(image) + eri = euca2ools.commands.euca.runinstances.RunInstances() + conn = eri.make_connection() + res = eri.make_request_cli(conn, 'run_instances', + image_id=image, + min_count=1, + max_count=1, + key_name=keypair, + security_groups=group, + instance_type=instance_type, + kernel_id=kernel, + ramdisk_id=ramdisk) + + instids = [ i.id for i in res.instances ] + + res_list = res.connection.get_all_instances(instids) + this_res = res_list[0] + if wait: + # wait here until the instances are up + num_running = 0 + while num_running != len(instids): + res_list = res.connection.get_all_instances(instids) + this_res = res_list[0] + num_running = len([ i for i in this_res.instances if i.state=='running' ]) + time.sleep(2) + + # there's only one - but maybe one day there could be more + instances = [] + for inst in this_res.instances: + d = { + 'id': inst.id, + 'public_ip': inst.ip_address, + } + instances.append(d) + + result = {"changed": True, + "instances": instances } + module.exit_json(**result) + +# this is magic, see lib/ansible/module_common.py +#<> + +main() diff --git a/playbooks/hosts/jenkins.cloud.fedoraproject.org.yml b/playbooks/hosts/jenkins.cloud.fedoraproject.org.yml new file mode 100644 index 0000000000..7b14bbda6d --- /dev/null +++ b/playbooks/hosts/jenkins.cloud.fedoraproject.org.yml @@ -0,0 +1,37 @@ +- name: check/create instance + hosts: 209.132.184.111 + user: root + gather_facts: False + + vars_files: + - /srv/web/infra/ansible/vars/global.yml + - ${private}/vars.yml + + tasks: + - include: $tasks/persistent_cloud.yml + +- name: provision instance + hosts: 209.132.184.111 + user: root + gather_facts: True + + vars_files: + - /srv/web/infra/ansible/vars/global.yml + - ${private}/vars.yml + - ${vars}/${ansible_distribution}.yml + + tasks: + - include: $tasks/cloud_setup_basic.yml + - name: install pkgs for jenkins + action: yum state=installed pkg=$item + with_items: + - vim + - java-1.7.0-openjdk + - subversion + - bzr + - git + tags: + - packages + + handlers: + - include: $handlers/restart_services.yml diff --git a/tasks/persistent_cloud.yml b/tasks/persistent_cloud.yml new file mode 100644 index 0000000000..764b46c7ed --- /dev/null +++ b/tasks/persistent_cloud.yml @@ -0,0 +1,19 @@ +--- +- name: check it out + local_action: shell nc -d -z -w 5 ${inventory_hostname} 22 >>/dev/null + register: host_is_up + ignore_errors: true + +- name: spin it up + local_action: ec2_create keypair=${keypair} image=${image} type=${instance_type} wait=true + register: inst_res + only_if: "'${host_is_up.rc}' != '0'" + +- name: assign it a special ip + local_action: shell euca-associate-address -i ${inst_res.instances[0].id} ${public_ip} + only_if: "'${host_is_up.rc}' != '0'" + +- name: wait for the reassignation + local_action: wait_for host=${public_ip} port=22 delay=20 timeout=300 + only_if: "'${host_is_up.rc}' != '0'" +