ansibleによるEC2・VPC環境構築(その2)

シルバーウィークに遅い夏休みを満喫した沼野井です。

・・・本当はこれ書いてるの9/14なんですが、公開日の調整の結果↑にような挨拶となりました。
こんな笑点みたいな挨拶をする機会があるとは思ってもいませんでした。

 

前回までのあらすじ

 

この構成をansibleで作ろう、と思うCoatiだった・・・

 

というわけで、前回の続きで、ansibleによるEC2・VPC環境構築の、実際のplaybookの内容についてです。

 

Playbookの内容

あ、前回すっかり忘れていたのですが、使用しているansibleのバージョンは 2.3 です。ご承知おきください。

Coatiチームで使用している、環境デプロイ用のPlaybookのディレクトリ構成は以下のようになっています。


├── ansible.cfg
├── group_vars
│   └── all.yml                       # 変数定義
├── hosts
├── roles
│   ├── VPC
│   │   └── tasks
│   │       ├── main.yml              # VPC.ymlの本体
│   │       ├── setup_ec2.yml         # VPC.ymlの本体
│   │       └── setup_vpc.yml         # VPC.ymlの本体
│   └── vpc_peering
│       └── tasks
│           ├── main.yml              # VPC.ymlの本体
│           └── vpc_peering.yml       # create_vpc_peering.ymlの本体
├── create_vpc_peering.yml            # 実行するplaybook
└── VPC.yml                           # 実行するplaybook

なんぞこれ? と目がハテナな方はこちら(英語ですが)
ansibleの標準的なディレクトリ構成と思っていただいてよいと思います。

個々に中身をご紹介していきます。

(1) group_vars/all.yml

全playbookで使う変数を定義しています。以下のような感じです。


PEER_OWNER_ID: 123456789012                      # お客様のAWSアカウント
PEERING_VPC_ID: vpc-XXXXXXXX                     # お客様のVPC ID
PEERING_VPC_CIDR: XXX.XXX.XXX.XXX/XX             # お客様のVPC CIDR
CUSTOMER: Coati Coffee.break.fun                 # お客様名
EMAIL: COATI@coati.coffee_break_fun.com          # お客様のEメールアドレス

PREFIX: "CoatiManager_{{ CUSTOMER }}"            # VPC, Subnet, ルートテーブル, インスタンス名のprefix
REGION: ap-northeast-1                           # リージョン(東京)
OFFICE_IP: ZZZ.ZZZ.ZZZ.ZZZ                       # SIOSのオペレーション端末のIPアドレス
OFFICE_IP_CIDR: "{{ OFFICE_IP }}/32"             # SIOSのオペレーション端末のIPアドレスのCIDR
VPC_NAME: "{{ PREFIX }}_VPC"                     # VPC名称
VPC_CIDR_LEFT: YYY.YYY.YYY                       # Coati ManagerのCIDRの左部分
VPC_CIDR_BLOCK: "{{ VPC_CIDR_LEFT }}.0/23"       # VPCのCIDR Block
SUBNET1_NAME: "{{ PREFIX }}_SUBNET1"             # Subnet名
SUBNET1_CIDR_BLOCK: "{{ VPC_CIDR_LEFT }}.0/24"   # SubnetのCIDR Block
ROUTETABLE1_NAME: "{{ PREFIX }}_RT1"             # ルートテーブル名

KEY_PAIR: XXXXXXXXXXXXXXXXXXXXXXXXXXX      # Coati Managerインスタンスにアクセスするためのキーペア
INSTANCE_TYPE: t2.small                # Coati Managerインスタンスのインスタンス・タイプ
EC2_NAME: "{{ PREFIX }}"                         # Coati Managerインスタンス名
EC2_PRIVATE_IP: "{{ VPC_CIDR_LEFT }}.10"         # Coati ManagerインスタンスのプライベートIPアドレス
IAM_ROLE: XXXXXXXXXXXX                           # Coati Managerインスタンスに割り当てるIAMロール
SIOS_ACCOUNT_ID: 987654321098                    # サイオスのAWSアカウントID

冒頭の5行の、


PEER_OWNER_ID: 123456789012                      # お客様のAWSアカウント
PEERING_VPC_ID: vpc-XXXXXXXX                     # お客様のVPC ID
PEERING_VPC_CIDR: XXX.XXX.XXX.XXX/XX             # お客様のVPC CIDR
CUSTOMER: Coati Coffee.break.fun                 # お客様名
EMAIL: COATI@coati.coffee_break_fun.com          # お客様のEメールアドレス

はお客様のお申込み内容に従って入力しています。残りの項目は固定値または、↑の内容から自動的に作成されるという寸法です。

(2) VPC.yml

VPCを作成して、その中にCoati Managerインスタンスを作成するplaybookです。インスタンスも作るのにVPC.ymlってネーミングがイマイチです。すみません。

そのネーミングのイマイチなVPC.ymlの中身はこんな感じです。


---
- name: setup localhost
  hosts: localhost
  
  roles:
    - VPC

こんだけ。

これは、「ロールVPCのタスクを実行しなさいね」と言ってるだけです。
ロールVPCのタスクとは


├── roles
│   ├── VPC
│   │   └── tasks
│   │       ├── main.yml              # VPC.ymlの本体
│   │       ├── setup_ec2.yml         # VPC.ymlの本体
│   │       └── setup_vpc.yml         # VPC.ymlの本体

こいつらです。実際にはmain.ymlがまず呼ばれます。

main.ymlは


---
- include: setup_vpc.yml
- include: setup_ec2.yml SUBNET_ID="{{ subnet.subnet.id }}"

これもこんだけで、本体であるsetup_vpc.ymlとsetup_ec2.ymlをincludeしています。

本体の1つ、setup_vpc.ymlの中身を見ていきます。


---
- name: Gather ec2 facts
  ec2_facts:
  register: ec2_facts

- name: Setup VPC
  ec2_vpc_net:
    name: "{{ VPC_NAME }}"
    cidr_block: "{{ VPC_CIDR_BLOCK }}"
    dns_hostnames: yes
    dns_support: yes
    region: "{{ REGION }}"
    tags:
      Role: CoatiManager
  register: vpc

- name: Setup subnet
  ec2_vpc_subnet:
    resource_tags:
    Name: "{{ SUBNET1_NAME }}"
    cidr: "{{ SUBNET1_CIDR_BLOCK }}"
    region: "{{ REGION }}"
    vpc_id: "{{ vpc.vpc.id }}"
  register: subnet

- name: Setup internet gateway
  ec2_vpc_igw:
    region: "{{ REGION }}"
    vpc_id: "{{ vpc.vpc.id }}"
  register: igw

- name: Setup route table
  ec2_vpc_route_table:
    resource_tags:
    Name: "{{ ROUTETABLE1_NAME }}"
    region: "{{ REGION }}"
    vpc_id: "{{ vpc.vpc.id }}"
    subnets:
      - "{{ subnet.subnet.id }}"
    routes:
      - dest: 0.0.0.0/0
        gateway_id: "{{ igw.gateway_id }}"
  register: route_table

- name: create temporary file
  lineinfile:
    dest: "/tmp/__temp_fact__.yml"
    create: yes
    line: "---\n"

- name: write vpc_id into temporary file
  lineinfile:
    dest: "/tmp/__temp_fact__.yml"
    line: "manager_vpc_id: {{ vpc.vpc.id }}\n"

- name: write route table id into temporary file
  lineinfile:
    dest: "/tmp/__temp_fact__.yml"
    line: "manager_route_table_id: {{ route_table.route_table.id }}\n"

- name: Setup security group. part 1
  ec2_group:
    name: default
    description: default VPC security group
    region: "{{ REGION }}"
    vpc_id: "{{ vpc.vpc.id }}"
    purge_rules: yes
    rules:
      - proto: tcp
        from_port: 80
        to_port: 80
        cidr_ip: 0.0.0.0/0
      - proto: tcp
        from_port: 22
        to_port: 22
        cidr_ip: "{{ OFFICE_IP_CIDR }}"
      - proto: tcp
        from_port: 22
        to_port: 22
        cidr_ip: "{{ ec2_facts.ansible_facts.ansible_ec2_public_ipv4 }}/32"
      - proto: icmp
        from_port: -1
        to_port: -1
        cidr_ip: "{{ OFFICE_IP_CIDR }}"
      - proto: icmp
        from_port: -1
        to_port: -1
        cidr_ip: "{{ ec2_facts.ansible_facts.ansible_ec2_public_ipv4 }}/32"
    changed_when: False
    register: default_sg

  - name: Setup security group. part 2
    ec2_group:
      name: default
      description: default VPC security group
      region: "{{ REGION }}"
      vpc_id: "{{ vpc.vpc.id }}"
      purge_rules: no
      rules:
        - proto: all
          from_port: 0
          to_port: 65535
          group_id: "{{ default_sg.group_id }}"
    changed_when: False

一転して長くなりましたね。本体ですから、実際いろいろやってます。順にみていきますと、


- name: Gather ec2 facts
  ec2_facts:
  register: ec2_facts

ec2_factsは(playbookを実行している)ホストの情報を色々集めてくるモジュールです。今回は、パブリックIPアドレスを取得するため(だけ)に使っています。
registerは、集めたネタを変数(この場合 変数名もec2_facts)に格納します。
実際にec2_factsを使っているところは後ほど!


- name: Setup VPC
  ec2_vpc_net:
    name: "{{ VPC_NAME }}"
    cidr_block: "{{ VPC_CIDR_BLOCK }}"
    dns_hostnames: yes
    dns_support: yes
    region: "{{ REGION }}"
    tags:
      Role: CoatiManager
  register: vpc

Coati Managerインスタンスを格納するVPCを作成しています。ec2_vpc_netモジュールを使います。

{{ VPC_NAME }} は group_vars/all.ymlで定義してあるものです(ansibleでは、”{{}}”で囲むと変数の値が取り出せます)
同様に{{VPC_CIDR_BLOCK}}, {{ REGION }}もgroup_vars/all.ymlで定義しています。
あと、tags:を利用して、 作成したVPCにRole=CoatiManager というタグをつけています。

ec2_vpc_netモジュールは、作成したVPCのIDなどを実行時の結果として戻しますので、実行結果をregisterで変数vpcに格納しておいて、あとで使うことができます。


- name: Setup subnet
  ec2_vpc_subnet:
    resource_tags:
    Name: "{{ SUBNET1_NAME }}"
    cidr: "{{ SUBNET1_CIDR_BLOCK }}"
    region: "{{ REGION }}"
    vpc_id: "{{ vpc.vpc.id }}"
  register: subnet

作ったVPCにsubnetを作成します。今作ったVPC IDが必要です。ここで、さきほどregisterで保存した変数vpcを使います。VPC IDは、


vpc_id: "{{ vpc.vpc.id }}"

のようにして参照できます。


- name: Setup internet gateway
  ec2_vpc_igw:
    region: "{{ REGION }}"
    vpc_id: "{{ vpc.vpc.id }}"
  register: igw

同様に、作成したVPCにインターネットゲートウェイを作成しています。ec2_vpc_igwモジュールを使います。

- name: Setup route table
  ec2_vpc_route_table:
    resource_tags:
    Name: "{{ ROUTETABLE1_NAME }}"
    region: "{{ REGION }}"
    vpc_id: "{{ vpc.vpc.id }}"
    subnets:
      - "{{ subnet.subnet.id }}"
    routes:
      - dest: 0.0.0.0/0
        gateway_id: "{{ igw.gateway_id }}"
  register: route_table

ルートテーブルの作成です。ec2_vpc_route_tableモジュールを使います。ちょっとパラメータが増えましたが、基本は同じです。
なお、ここでは送信先を0.0.0.0/0にしていますが、適切に設定してくださいね!


- name: Setup security group. part 1
  ec2_group:
    name: default
    description: default VPC security group
    region: "{{ REGION }}"
    vpc_id: "{{ vpc.vpc.id }}"
    purge_rules: yes
    rules:
      - proto: tcp
        from_port: 80
        to_port: 80
        cidr_ip: 0.0.0.0/0
      - proto: tcp
        from_port: 22
        to_port: 22
        cidr_ip: "{{ OFFICE_IP_CIDR }}"
      - proto: tcp
        from_port: 22
        to_port: 22
        cidr_ip: "{{ ec2_facts.ansible_facts.ansible_ec2_public_ipv4 }}/32"
      - proto: icmp
        from_port: -1
        to_port: -1
        cidr_ip: "{{ OFFICE_IP_CIDR }}"
      - proto: icmp
        from_port: -1
        to_port: -1
        cidr_ip: "{{ ec2_facts.ansible_facts.ansible_ec2_public_ipv4 }}/32"
    changed_when: False
    register: default_sg

セキュリティグループの作成です。ec2_groupモジュールを使います。以下のポートに穴をあけています。

ポート番号 ソース 備考
80 0.0.0.0/0(※)
22 手元のPCのIPアドレス 私がオフィスから直接ログインして操作するため
22 オペレーション端末のIPアドレス オペレーション端末からログインして色々設定するため
-1 手元のPCのIPアドレス ICMPです。ping用
-1 オペレーション端末のIPアドレス ICMPです。ping用

※ここでは0.0.0.0/0と書いてありますが、適切に設定してくださいね!

「オペレーション端末の(グローバル)IPアドレス」の指定に、最初の方で取っておいたec2_factsを使っています。
やっと伏線回収できました!


  - name: Setup security group. part 2
    ec2_group:
      name: default
      description: default VPC security group
      region: "{{ REGION }}"
      vpc_id: "{{ vpc.vpc.id }}"
      purge_rules: no
      rules:
        - proto: all
          from_port: 0
          to_port: 65535
          group_id: "{{ default_sg.group_id }}"
    changed_when: False

セキュリティグループ構築その2、です。同じセキュリティグループに割り当てられたインスタンスからのトラフィックを許可しています。

 

ここまでの結果

・・・いかがでしたでしょうか。ここまでで、

 

の構成ができました。

 

少し長くなってしまったので、Coati Managerインスタンスの作成とVPC Peeringの設定は次回にしようと思います!

ソニー様の「マネージドクラウド with AWS」のソリューションメニューとして提供が開始されます!

皆様、こんにちは、SIOS Coatiのマーケティング担当をしております吉岡です。

この度SIOS Coatiはソニーネットワークコミュニケーションズ社が提供する「マネージドクラウド with AWS」のソリューションパッケージとして
販売を開始していただくこととなりました!

詳細はこちらからご覧ください!

こちらのソリューションはAWS Roadshowでご覧いただけますので、ぜひお立ち寄りください!

9/21(木)大阪会場
9/27(水)名古屋会場

Amazon Linuxに対応しました

SIOS Coati開発チームの清水です。

先日のアップデートで、SIOS Coatiで監視できるOSとして Amazon Linux に対応しました!

Amazon Linuxとは、EC2 Management Console上からインスタンスを作るとき一番上に表示されるAMIです。

AWSが公式で提供しているAMIということもあり、使用している方も多いのではないかと思われます。

このAmazon Linuxのインスタンスも、これまでサポートしていたRHELやCentOSと同様の手順ですぐに使い始めることができます。

もし「使ってみたいけどAmazon Linuxを使ってるんだよなあ…」と思っていた方は、是非この機会に無料トライアルでお試しください。こちらの製品ページから申し込むことができます!

SIOS Coatiのオンラインマニュアルの作成方法(後編)

始めに

SIOS Coatiのチームにいる高正(たかしょう)です。
みなさまいかがお過ごしでしょうか。私は先日、夏休みをとって、家族で山梨県に旅行に行ってきました。
昨年も山梨県で今年も山梨県です。特に山梨に所縁はありませんが、去年旅行に行って気に入ったので今年も山梨に赴いた感じです。山梨のおすすめスポット色々あると思いますが、私のおすすめスポットは、ほったらかし温泉です。なんでほったらかし温泉という名前であるかは公式のホームページにお任せしましょう。私がおすすめする理由はただ一つ、景色が良いからです。ここの温泉はあっちの湯、こっちの湯と2つの温泉があります。去年はこっちの湯に入り、今年はあっちの湯に入りました。それぞれ微妙に違いがあって良いです。どのように違うかは実際に行って体験してみたください。ちなみに、天気がよければ富士山がとーってもきれいにみれるビュースポットなのですが、実は私、去年も今年も富士山を拝むことはできていません。いつの日か素敵な富士山を見たいものです。

オンラインマニュアルをデプロイするまでの流れ

前回の記事ではマニュアルの作成はSphinxを使って、マニュアルのデプロイにはBitbucket Pipelinesを使っていると説明しましたが、これらについて具体的などのようなプロセスを経てデプロイされるか説明をしたいと思います。

ざっくりとうちの開発チームにおけるデプロイまでの流れを書くと以下のようになります。

1.reStructuredText(reST)*1で書いたマニュアル用のソースコードを開発用ブランチにコミットする

2.開発用ブランチへのソースコードのコミットを契機にステージング用のS3バケットのマニュアルをデプロイ*2する

3.2のレビューで問題がなければ、本番用ブランチにソースコードをマージしてプロダクション用のS3バケットにマニュアルをデプロイ*2する

*1.reStructuredText(reST)はSphinxで採用されているマークアップ言語です。Markdown記法と似ています。Markdownを理解している方であれば、比較的簡単にreSTを使えると思います。

*2.Bitbucket Pipelinesはざっくりといえば、リポジトリへのコミットを契機に、環境をデプロイするサービスです。現在、SIOS CoatiではBitbucket PipelinesをオンラインマニュアルをS3のデプロイするために利用しています。

利点

ちょいとわかりづらいと思いますが、この流れに共通している名詞にお気づきでしょうか。はい、ソースコードです。この方式の良い点はreSTの書き方さえ抑えてしまえば、製品コードを書くのと同じ感覚でオンラインマニュアルの作成が行える点です。ちなみに、BitbucketがreSTに対応しているのでマニュアルの大まかな確認はBitbucket上で行えます。オンラインマニュアルの構造など、全体の見た目の部分はS3にデプロイされたhtmlファイルを見れば確認できます。

今後の展望

デプロイ作業は今回の記事で説明している方式によりとても簡単になりました。しかし、マニュアルの中身という点では表記揺れがあったり、冗長な表現があったりと改善したい箇所があります。SIOS Coatiでは文章校正は現在、人力でやっています。できれば、これは人力ではなく、ツールで解消したいところです。文章校正のツールとしては、RedPentextlintがあります。今後はこれらのツールを使って、文章校正の手間を極力軽減して、マニュアル作成を楽しく行える環境にしていきたいと思います。

『SIOS Coatiの申し込みから利用開始までのプロセス』更新のお知らせ

こんにちは、SIOS Coatiチームの黒田です。
前回の記事で、『AWS認証方式の変更のお知らせ』を紹介しましたが、AWS認証方式の変更により
『SIOS Coatiの申し込みから利用開始までのプロセス』を更新しましたので、再度、Coatiの申し込みから利用開始までのプロセスをSTEP1~7を紹介したいと思います。

Coatiの申し込みから導入までのプロセス
STEP1 Coatiの申し込み
STEP2 ヘルプデスクアカウントの登録
STEP3 VPC Peeringリクエストの承認
STEP4 ルートテーブルとセキュリティーグループの設定
STEP5 AWSの認証情報の登録
STEP6 監視対象のインスタンスでスクリプト実行
STEP7 Coatiの利用開始

続きを読む