Ansible AWXをAWSへインストールするPlaybookを書いた

Ansible AWXをAWSへインストールするAnsible Playbookを書いてみました。

[ansible-centos7/ansible-awx | GitHub](https://github.com/ansible-centos7/ansible-awx)


## 動作確認OS

以下のイメージで動作確認済みです。

* [CentOS 7 (x86_64) - with Updates HVM](https://aws.amazon.com/marketplace/pp/B00O7WM7QW?ref=cns_srchrow)
* [AWS Marketplace: Ubuntu 18.04 LTS - Bionic](https://aws.amazon.com/marketplace/pp/B07CQ33QKV)

## VPCの構成

### CloudFormationのデザイナーで出力した図

<img width="971" alt="スクリーンショット 2019-07-08 16.08.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/a9578e92-5610-3d47-50dd-263030daa97b.png">


### VPCのCloudFormation Template

```yaml:cloudformation-template.yaml
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t2.micro
    ConstraintDescription: must be a valid EC2 instance type.
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.

Mappings:
  StackConfigs:
    VPC:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
    PublicSubnet:
      AvailabilityZone: "ap-northeast-1a"
      CidrBlock: 10.0.1.0/24
      Name: "10.0.1.0 - ap-northeast-1a"

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !FindInMap [StackConfigs, VPC, CidrBlock]
      EnableDnsSupport: !FindInMap [StackConfigs, VPC, EnableDnsSupport]
      EnableDnsHostnames: !FindInMap [StackConfigs, VPC, EnableDnsHostnames]
      Tags:
      - Key: Name
        Value: !Ref AWS::StackName

  GatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId:
        Ref: VPC
      InternetGatewayId:
        Ref: InternetGateway

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !FindInMap [StackConfigs, PublicSubnet, AvailabilityZone]
      CidrBlock: !FindInMap [StackConfigs, PublicSubnet, CidrBlock]
      MapPublicIpOnLaunch: 'true'
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: !FindInMap [StackConfigs, PublicSubnet, Name]

  centos7:
    Type: AWS::EC2::Instance
    DependsOn: InternetGateway
    Properties:
      BlockDeviceMappings:
        - DeviceName: /dev/sda1
          Ebs:
            DeleteOnTermination: true
            VolumeType: gp2
      ImageId: ami-045f38c93733dd48d
      InstanceType: !Ref 'InstanceType'
      KeyName: !Ref 'KeyName'
      SecurityGroupIds:
        - !Ref sshSG
        - !Ref httpSG
      SubnetId:
        Ref: PublicSubnet
      Tags:
      - Key: Name
        Value: !Ref AWS::StackName
      - Key: ansible_inventory_group_name
        Value: centos7
      - Key: ansible_user
        Value: centos
      - Key: ansible_port
        Value: 22


  ubuntu18:
    Type: AWS::EC2::Instance
    DependsOn: InternetGateway
    Properties:
      ImageId: ami-09c81ecf1c2b2ef70
      InstanceType: !Ref 'InstanceType'
      KeyName: !Ref 'KeyName'
      SecurityGroupIds:
        - !Ref sshSG
        - !Ref httpSG
      SubnetId:
        Ref: PublicSubnet
      Tags:
      - Key: Name
        Value: !Ref AWS::StackName
      - Key: ansible_inventory_group_name
        Value: ubuntu18
      - Key: ansible_user
        Value: ubuntu
      - Key: ansible_port
        Value: 22


  sshSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: ssh
      GroupDescription: SSH access rule
      SecurityGroupIngress:
      - CidrIp: 0.0.0.0/0
        FromPort: 22
        IpProtocol: tcp
        ToPort: 22
      VpcId:
        Ref: VPC

  httpSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: http
      GroupDescription: http access rule
      SecurityGroupIngress:
      - CidrIp: 0.0.0.0/0
        FromPort: 80
        IpProtocol: tcp
        ToPort: 80
      VpcId:
        Ref: VPC

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Name
        Value: InternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: public

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGateway
    Properties:
      RouteTableId:
        Ref: PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId:
        Ref: InternetGateway

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: PublicSubnet
      RouteTableId:
        Ref: PublicRouteTable

Outputs:
  VpcId:
    Value: !Ref VPC
```

## 主な機能

GitHubの公開リポジトリからansible.cfgを取得してawx_taskコンテナの「/etc/ansible/ansible.cfg」へ上書きします。リポジトリのURLが設定されていない場合は初期設定の状態のansible.cfgがロードされます。

AWXでansible.cfgを設定する場合、docker execコマンド等を利用してコンテナの「/etc/ansible/ansible.cfg」を編集する必要があります。

カスタマイズしたansible.cfgをGitHub等へ配置しておき、Playbook実行時にURLを指定するとこの手間が省けます。

- 推奨されるEC2インスタンスのサイズ:  t2.medium以上

- インストールされるAWXのバージョン:  9.0.1
- ansible.cfgのGitHub URL:  未設定
- https:  未設定

## Ansible Vars

```bash:vars/default.yml
#AWX GitHub URL
awx_repo_url: https://github.com/ansible/awx.git

#AWX GitHub branch name or tags to retrieve
#Default is 5.0.0 
awx_repo_version: 5.0.0 

# Costomized ansible.cfg url
ansiblecfg_repo_url:

#ansible.cfg GitHub branch name or tags to retrieve
#Default is master 
ansiblecfg_repo_version: master

# Playbook  working directory
work_dir: /tmp/awx-install
```


## 使い方

```bash:カスタマイズansible.cfgを利用しない場合
# インストールPlaybookを取得する
git clone https://github.com/ansible-centos7/ansible-awx

# ディレクトリを移動する
cd ansible-awx

# 必要なAnsible Galaxy roleをインストールする / 「playbookdir/roles」へインストールされる
ansible-galaxy install -r roles/requirements.yml -p roles/

# Playbookを実行する
ansible-playbook -i "ec2-instance-IPv4-address," -u centos(もしくはubuntu) --private-key /path/to/ec2-pair-key.pem install.yml
```

```bash:カスタマイズansible.cfgを利用する場合
# インストールPlaybookを取得する
git clone https://github.com/ansible-centos7/ansible-awx

# ディレクトリを移動する
cd ansible-awx

# 必要なAnsible Galaxy roleをインストールする / 「playbookdir/roles」へインストールされる
ansible-galaxy install -r roles/requirements.yml -p roles/

# Playbookを実行する
ansible-playbook -i "ec2-instance-IPv4-address," -u centos(もしくはubuntu) --private-key /path/to/ec2-pair-key.pem install.yml -e ansiblecfg_repo_url=https://github.com/TomonoriMatsumura/ansible-cfg.git
```

## 参考サイト

* [awx | Ansible Galaxy](https://galaxy.ansible.com/geerlingguy/awx)
* [Ansible Tower/AWXのアーキテクチャとジョブ実行の仕組み(1) - Qiita](https://qiita.com/saito_hideki/items/e19f39f792eb7d0e720c)