LoginSignup
0
0

【Pulumi×Ansible】PulumiでAnsible Navigatorを使用可能なEC2インスタンスを構築したい

Last updated at Posted at 2024-06-23

はじめに

過去の記事(【Pulumi】Pulumi AIが生成したコードでEC2インスタンスを構築したい~第1章:YAML編~)では、
Pulumi AIで生成したYAMLをもとにしてEC2インスタンスを構築しました。
今回はEC2インスタンス構築後にスクリプトを実行して、Ansible Navigatorを使用可能な環境を構築します。

TL;DR

  • PulumiでEC2インスタンス構築後にスクリプトを実行するには、aws:ec2:InstanceuserDataの箇所にスクリプトを記載する
  • スクリプトはrootユーザーで実行されるので、特定のユーザーでの処理がある場合はsuコマンドでユーザーを切り替える

前提条件

PulumiでAWSを操作するには以下が必要です

  • Pulumiのアカウントを所持していること
  • AWSにてIAMユーザーのアクセスキーが作成してあること

実行環境

  • Amazon マシンイメージ(AMI)
    • Amazon Linux 2023 AMI
  • Pulumi
    • v3.112.0

詳細

1. 事前準備

2. AWSリソースの定義ファイル作成

  1. AWSリソースの定義ファイル(Pulumi.yaml)を以下のように記載する

    ---
    name: quickstart
    runtime: yaml
    description: A program to create an AWS EC2 instance within a VPC with a subnet and security group, accessible over the internet.
    variables:
      amiId: "<amiId>"    # ex) ami-xxxxxxxxxxxxxxxxx
      keyName: "<keyName>"
      instanceType: "<instanceType>"    # ex) t2.micro
    resources:
      # Create a new VPC
      myVpc:
        type: aws:ec2:Vpc
        properties:
          cidrBlock: "10.0.0.0/16"
          tags:
            Name: "my-vpc"
    
      # Create an Internet Gateway
      myInternetGateway:
        type: aws:ec2:InternetGateway
        properties:
          vpcId: ${myVpc.id}
          tags:
            Name: "my-internet-gateway"
    
      # Create a new Subnet within the VPC
      mySubnet:
        type: aws:ec2:Subnet
        properties:
          vpcId: ${myVpc.id}
          cidrBlock: "10.0.1.0/24"
          mapPublicIpOnLaunch: true
          availabilityZone: ${aws:region}a
          tags:
            Name: "my-subnet"
    
      # Create a new Route Table
      myRouteTable:
        type: aws:ec2:RouteTable
        properties:
          vpcId: ${myVpc.id}
          tags:
            Name: "my-route-table"
    
      # Create a route that directs 0.0.0.0/0 to the Internet Gateway
      myRoute:
        type: aws:ec2:Route
        properties:
          destinationCidrBlock: "0.0.0.0/0"
          gatewayId: ${myInternetGateway.id}
          routeTableId: ${myRouteTable.id}
    
      # Associate the Route Table with the Subnet
      myRouteTableAssociation:
        type: aws:ec2:RouteTableAssociation
        properties:
          subnetId: ${mySubnet.id}
          routeTableId: ${myRouteTable.id}
    
      # Create a Security Group within the VPC
      mySecurityGroup:
        type: aws:ec2:SecurityGroup
        properties:
          vpcId: ${myVpc.id}
          description: "Allow SSH inbound traffic"
          tags:
            Name: "my-security-group"
          ingress:
            - protocol: "tcp"
              fromPort: 22
              toPort: 22
              cidrBlocks: ["0.0.0.0/0"]
          egress:
            - protocol: "-1" # Allow all outbound traffic
              fromPort: 0
              toPort: 0
              cidrBlocks: ["0.0.0.0/0"]
    
      # Launch an EC2 instance within the subnet
      myInstance:
        type: aws:ec2:Instance
        properties:
          ami: ${amiId}
          instanceType: ${instanceType}
          subnetId: ${mySubnet.id}
          securityGroups: ["${mySecurityGroup.id}"]
          availabilityZone: ${aws:region}a
          keyName: ${keyName}
          userData: |
            #!/bin/bash
    
            dnf install -y podman python3-pip
            su ec2-user << EOF
            podman pull ghcr.io/ansible-community/community-ee-base:latest
            python3 -m pip install ansible-navigator --user
            echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.profile
            EOF
          tags:
            Name: "my-instance"
    
    outputs:
      vpcId: ${myVpc.id}
      subnetId: ${mySubnet.id}
      internetGatewayId: ${myInternetGateway.id}
      routeTableId: ${myRouteTable.id}
      routeTableAssociationId: ${myRouteTableAssociation.id}
      routeID: ${myRoute.id}
      securityGroupId: ${mySecurityGroup.id}
      instanceId: ${myInstance.id}
      instancePublicIp: ${myInstance.publicIp}
    
    • ポイントは以下の通り
      1. AMI IDはRHEL9を指定する
      2. aws:ec2:InstanceuserDataの箇所に、インスタンスの構築後に実行したいスクリプトを記述する
      3. スクリプトはrootユーザーで実行される。そのため、特定のユーザー(今回はec2-user)での
        処理をしたい場合は、suコマンドでユーザーを切り替える必要がある

3. Pulumiによるリソースの作成

  1. IAMユーザーのアクセスキーを登録する

    $ export AWS_ACCESS_KEY_ID="<YOUR_ACCESS_KEY_ID>"
    $ export AWS_SECRET_ACCESS_KEY="<YOUR_SECRET_ACCESS_KEY>"
    
  2. リソースを作成する

    $ pulumi up
    
  3. リソースが作成されていることを確認する(以下はログの一部)

        Type                              Name                     Status              
    +   pulumi:pulumi:Stack               quickstart-dev           created (47s)       
    +   ├─ aws:ec2:Vpc                    myVpc                    created (1s)        
    +   ├─ aws:ec2:SecurityGroup          mySecurityGroup          created (3s)        
    +   ├─ aws:ec2:InternetGateway        myInternetGateway        created (0.78s)     
    +   ├─ aws:ec2:Subnet                 mySubnet                 created (11s)       
    +   ├─ aws:ec2:RouteTable             myRouteTable             created (1s)        
    +   ├─ aws:ec2:Route                  myRoute                  created (0.73s)     
    +   ├─ aws:ec2:RouteTableAssociation  myRouteTableAssociation  created (0.91s)     
    +   └─ aws:ec2:Instance               myInstance               created (32s)  
    

4. Ansible Navigatorの実行確認

  1. 構築されたEC2インスタンスにログインする

    • user:ec2-user(ユーザー名はAMI IDによって異なります)
  2. Ansible実行環境イメージが存在することを確認する

    $ podman images
    REPOSITORY                                   TAG         IMAGE ID      CREATED     SIZE
    ghcr.io/ansible-community/community-ee-base  latest      71b6d35cd089  2 days ago  347 MB
    
  3. テスト用のPlaybookを作成する

    $ vi playbook.yml
    
    ---
    - name: Sample Play
      hosts: localhost
      gather_facts: false
      tasks:
        - name: Hello World!
          ansible.builtin.debug:
            msg: "Hello World!"
    
  4. Playbookを実行する

    $ ansible-navigator run playbook.yml --eei ghcr.io/ansible-community/community-ee-base --pp never -m stdout
    
    PLAY [Sample Play] *************************************************************
    
    TASK [Hello World!] ************************************************************
    ok: [localhost] => {
        "msg": "Hello World!"
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

さいごに

  • AWSリソースの定義ファイル(Pulumi.yaml)で、EC2インスタンス構築後に実行するスクリプトを書けるのは便利だと感じます
  • AWSリソースの定義ファイル(Pulumi.yaml)は複数のEC2インスタンスを構築することも可能なので、
    Ansibleの対象機器も構築できれば開発の更なる効率化が見込めるのではないかと思います

参考URL

関連記事


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0