Ansibleでalbに動的にEC2インスタンスを追加する

f:id:sktktk1230:20180726121250p:plain

最近Ansibleを使ってAWSの環境構築をしており、タイトルの通りのことをやりたかったのですが、かなりハマってしまった為、自分へのメモも兼ねて書きます

やりたかったこと

こちらの図のようにパブリックサブネットのALBにプライベートサブネットのEC2インスタンスを接続するみたいな作りでEC2インスタンスの台数を増やしても勝手に追加してくれるようにしたかった

publicサブネットにalbを置き、privateサブネットのec2インスタンスにバランシングするという構成です

f:id:sktktk1230:20180803110555p:plain

うまくいかなかったやりかた

Ansibleモジュールのこの3つを使って、やろうとしていました
複数台生成したEC2インスタンスをtarget_groupに動的に追加して、target_groupをalbに追加するという形です

1. ec2

- name: Set up about EC2 instance for Web
  ec2:
    aws_access_key: "{{aws_access_key}}"
    aws_secret_key: "{{aws_secret_key}}"
    region: "{{region}}"
    group: default
    image: ami-e99f4896
    instance_tags:
      Name: web
    instance_type: t2.micro
    monitoring: yes
    vpc_subnet_id: "{{private_subnet_az_c.subnet.id}}"
    exact_count: 2
    count_tag:
      Name: web
    wait: yes
  register: ec2_web

- debug: var=ec2_web

2. elb_target_group

- name: Set up about elb target Group
  elb_target_group:
    aws_access_key: "{{aws_access_key}}"
    aws_secret_key: "{{aws_secret_key}}"
    region: "{{region}}"
    health_check_protocol: http
    name: web-ec2-instances
    protocol: http
    port: 80
    state: present
    stickiness_enabled: yes
    targets:
      - Id: "{{ item.id }}"
      - Port: 80
    vpc_id: '{{vpc.vpcs | map(attribute="id") | first }}'
  with_items: "{{ ec2_web.tagged_instances }}"
  register: elb_target_group

- debug: var=elb_target_group

3. elb_application_lb

- name: Set up about Application Load Balancer
  elb_application_lb:
    aws_access_key: "{{aws_access_key}}"
    aws_secret_key: "{{aws_secret_key}}"
    region: "{{region}}"
    name: alb_for_web_ec2_instance
    state: present
    subnets:
      - "{{public_subnet_az_a.subnet}}"
    listeners:
      - Protocol: HTTP
        Port: 80
        DefaultActions:
          - Type: forward
            TargetGroupName: web-ec2-instances

これで実行すると、elb_target_groupのtargetsがうまく設定されません
例えば、ec2インスタンス2台を設定する場合だと、 1. elb_target_groupに1台目のec2インスタンスを設定 2. 1で設定したec2インスタンスのターゲットを削除し、2台目を設定

となり、結果はalbに1台だけ設定されているという状態でした

うまくいった方法

よくよく調べてみるとelb_targetというモジュールが用意されており、こちらで1台ずつec2インスタンスをtargetとして設定しelb_targetをelb_target_groupにまとめて設定というやりかたで解決できました

elb_targetに対して、EC2のインスタンスの台数分 with_itemsでループを回して設定し、elb_taget_group名を指定してグループに作成したelb_targetを追加しました

1. elb_target

- name: Set up about elb target
  elb_target:
    aws_access_key: "{{aws_access_key}}"
    aws_secret_key: "{{aws_secret_key}}"
    region: "{{region}}"
    target_group_name: web-ec2-instances
    target_id: "{{ item.id }}"
    state: present
  with_items: "{{ ec2_web.tagged_instances }}"
  register: elb_target_group

- debug: var=elb_target_group

2. elb_target_group

- name: Set up about elb target Group
  elb_target_group:
    aws_access_key: "{{aws_access_key}}"
    aws_secret_key: "{{aws_secret_key}}"
    region: "{{region}}"
    health_check_protocol: http
    name: web-ec2-instances
    protocol: http
    port: 80
    state: present
    stickiness_enabled: yes
    vpc_id: '{{vpc.vpcs | map(attribute="id") | first }}'
  register: elb_target_group

- debug: var=elb_target_group

まとめ

Ansibleドキュメントはしっかりと読んで別モジュールを探せば解決法はあるという当たり前すぎる学びでした