简体   繁体   English

通过 ansible 在具有两个网卡的 vpc 中创建 ec2 实例

[英]Create ec2 instance within vpc with two nics through ansible

after a day of googling I decided to give up and ask here: I'm still quite new to ansible and AWS, hence this question might lack background information which I'm happy to provide on request.经过一天的谷歌搜索后,我决定放弃并在这里提问:我对 ansible 和 AWS 还是很陌生,因此这个问题可能缺少背景信息,我很乐意应要求提供这些信息。

What I'm trying to achieve: Write an Ansible playbook, which creates a new ec2 instance within my vpc.我想要实现的目标:编写一个 Ansible 剧本,它在我的 vpc 中创建一个新的 ec2 实例。 This instance shall be provided with two new nics, eth0 and eth1.该实例应配备两个新网卡,eth0 和 eth1。 These nics should be associated with each one specific security group.这些网卡应该与每个特定的安全组相关联。

My playbook so far is built like this:到目前为止,我的剧本是这样构建的:

  • Create eth0创建eth0
  • Create eth1创建eth1
  • Create ec2 instance创建 ec2 实例

My problem: All documentation says I need to provide the eni-id of the interface I'd like to attach to my instance.我的问题:所有文档都说我需要提供我想附加到我的实例的接口的 eni-id。 I can't provide this, since the ids do not exist yet.我无法提供此信息,因为 ID 尚不存在。 The only thing I know is the name of the interfaces so I was trying to get the id of the interfaces separately, which also didn't work.我唯一知道的是接口的名称,所以我试图分别获取接口的 ID,但这也没有用。 If I try to register the output of the creation of eth{0,1} in ansible, the whole output is stored and breaks the validation later when calling the variables in the section of the instance creation.如果我尝试在 ansible 中注册创建 eth{0,1} 的 output,则会存储整个 output 并在稍后调用实例创建部分中的变量时中断验证。 Same with the extra step after the creation process.与创建过程后的额外步骤相同。

More about the setup: Running a VPC in AWS, hosts inside VPC are only accessible through VPN.有关设置的更多信息:在 AWS 中运行 VPC,VPC 内的主机只能通过 VPN 访问。 Running Ansible on macOS:在 macOS 上运行 Ansible:

ansible --version

ansible [core 2.14.1]
  config file = None
  configured module search path = ['/Users/mg/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/Cellar/ansible/7.1.0/libexec/lib/python3.11/site-packages/ansible
  ansible collection location = /Users/mg/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.11.1 (main, Dec 23 2022, 09:40:27) [Clang 14.0.0 (clang-1400.0.29.202)] (/usr/local/Cellar/ansible/7.1.0/libexec/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True

Playbook:剧本:


---
- name: Create ec2 instances
  hosts: localhost
  gather_facts: false
  tasks:

  # Block is a Group of Tasks combined together
  - name: Get Info Block
    block: 
      - name: Get Running instance Info
        
        ec2_instance_info:
        register: ec2info 

      - name: Print info
        debug: var="ec2info.instances"
             

    # By specifying always on the tag, 
    # I let this block to run all the time by module_default
    # this is for security to net create ec2 instances accidentally
    tags: ['always', 'getinfoonly']

  - name: Create ec2 block
    block: 
    
      - amazon.aws.ec2_vpc_net_info:
          vpc_ids: vpc-XXXXXXXXXXXXXXXXX
                                 
      - name: Create ec2 network interface eth0_lan
        delegate_to: localhost
        tags: ec2-create
        amazon.aws.ec2_eni:
          name: "eth0_lan_{{ vpc_hostname }}"
          description: "eth0_lan_{{ vpc_hostname }}"
          subnet_id: "{{ vpc_subnetid }}"
          state: present
          delete_on_termination: true
          region: eu-central-1
          security_groups: "sg-XXXXXXXXXXXXXXXXX"
      
      - name: Get id of eth0
        delegate_to: localhost
        tags: ec2-create
        amazon.aws.ec2_eni:
          name: "eth0_lan_{{ vpc_hostname }}"
        register: eth0
      

      - name: Create ec2 network interface eth1_wan
        delegate_to: localhost
        tags: ec2-create
        amazon.aws.ec2_eni:
          name: "eth1_wan_{{ vpc_hostname }}"
          description: "eth1_wan_{{ vpc_hostname }}"
          subnet_id: "subnet-XXXXXXXXXXXXXXXXX"
          state: present
          delete_on_termination: true
          region: eu-central-1
          security_groups: 'sg-XXXXXXXXXXXXXXXXX'

      - name: Get id of eth1
        delegate_to: localhost
        tags: ec2-create
        amazon.aws.ec2_eni:
          name: "eth1_wan_{{ vpc_hostname }}"
        register: eth1

      - name: Launch ec2 instances
        tags: ec2-create
        amazon.aws.ec2_instance:
          name: "{{ vpc_hostname }}"
          region: "eu-central-1"
          key_name: "MyKey"
          image_id: ami-XXXXXXXXXXXXXXXXX
          vpc_subnet_id: "{{ vpc_subnetid }}"
          instance_type: "{{ instance_type }}"
          volumes:
            - device_name: /dev/sda1
              ebs:
                volume_size: 30
                delete_on_termination: true
          network:
            interfaces:
              - id: "{{ eth0 }}"
              - id: "{{ eth1 }}"
          detailed_monitoring: true
        register: ec2
        delegate_to: localhost

    # By specifying never on the tag of this block, 
    # I let this block to run only when explicitely being called
    tags: ['never', 'ec2-create']

(If you're wondering about the tag-stuff, this comes from the tutorial I followed initially, credits: https://www.middlewareinventory.com/blog/ansible-aws-ec2/#How_Ansible_works_with_AWS_EC2_Setup_Boto_for_Ansible ) (如果您想了解标签内容,这来自我最初遵循的教程,学分: https://www.middlewareinventory.com/blog/ansible-aws-ec2/#How_Ansible_works_with_AWS_EC2_Setup_Boto_for_Ansible

The execution of the ansible playbook breaks with this error: ansible 剧本的执行因以下错误而中断:

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: Invalid type for parameter NetworkInterfaces[1].NetworkInterfaceId, value: {'changed': True, 'interface': {'id': 'eni-XXXXXXXXXXXXXXXXX', 'subnet_id': 'subnet-XXXXXXXXXXXXXXXXX', 'vpc_id': 'vpc-XXXXXXXXXXXXXXXXX', 'description': 'somedescription', 'owner_id': 'XXXXXXXXXXXXXXXXX', 'status': 'available', 'mac_address': 'xx:xx:xx:xx:xx:xx, 'private_ip_address': 'xx.xx.xxx.xx', 'source_dest_check': True, 'groups': {'sg-XXXXXXXXXXXXXXXXX': 'SGNAME'}, 'private_ip_addresses': [{'private_ip_address': 'xx.xx.xxx.xx', 'primary_address': True}], 'name': 'eth1_wan_<fqdn>', 'tags': {'Name': 'eth1_wan_<fqdn>'}}, 'failed': False}, type: <class 'dict'>, valid types: <class 'str'>

So, my colleague and I managed to solve this: Use "{{ eth0.interface.id }}" instead.所以,我和我的同事设法解决了这个问题:改用“{{ eth0.interface.id }}”。 However, all instances continue to terminate themselves on creation.然而,所有实例在创建时继续自行终止。 In AWS console: Client.InternalError.在 AWS 控制台中:Client.InternalError。 This is related to kms/ebs encryption which I turned on by default today.这与我今天默认打开的 kms/ebs 加密有关。 It turned out, that I tried to use an asymmetrical customer-managed-key for default ebs encryption.事实证明,我尝试使用非对称客户管理密钥进行默认 ebs 加密。 As soon as I replaced this with a symmetrical one, it worked and the instances would start.一旦我用一个对称的替换它,它就起作用了,实例就会开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM