0
0

More than 3 years have passed since last update.

軽作業用インスタンス構築に AWS CloudFormation を利用しました

Last updated at Posted at 2020-01-31

背景

軽作業のためにインスタンスが欲しくなるときがあります。
そういうケースは、マネコンからEIP、t3.nano、セキュリティグループリソースを手動で構成しています。
不要になると同じようにマネコンから手動で削除しています。
このオペレーションをAWS CloudFormationのテンプレートを利用して自動化化した記録。

AWS CloudFormation

公式サイトからの引用

AWS CloudFormation は、クラウド環境で AWS とサードパーティ製アプリケーションリソースのモデリングおよびプロビジョニングをする際の、共通的な手法を提供します。AWS CloudFormation では、プログラミング言語またはシンプルなテキストファイルを使用して、あらゆるリージョンとアカウントでアプリケーションに必要とされるすべてのリソースを、自動化された安全な方法でモデル化し、プロビジョニングできます。これは、AWS とサードパーティ製のリソースに真に単一のソースを与えます。

AWS公式サイト AWS CloudFormation

今回、実現したいこと

  • パブリックからつながるEC2インスタンス
  • 特定IPからのみ ssh できるEC2インスタンス
  • aws cli を使いたい
  • aws cli の config に東京リージョンを指定したい
  • git コマンド使いたい
  • リソースへの権限がEC2インスタンスに欲しい
    • IAM
    • CloudFormation
    • EC2
    • S3
    • Lambda

テンプレート

YAML形式で記述しました

デザイナーを利用する場合の注意事項が記載されています。

デザイナー のテンプレートに # YAML コメントを追加しないことをお勧めします。YAML テンプレートに # コメントがある場合、デザイナー は、テンプレートを JSON に変換する際にコメントを保持しません。また、デザイナー でテンプレートを変更する場合 (たとえば、キャンバスにリソースを移動する場合)、コメントは失われます。

AWS公式サイト AWS CloudFormation テンプレート形式

テンプレートは、

メタデータ

パラメータをグルーピングして表示できるよう指定しました。
今回は、ネットワーク関連と作業用インスタンス関連の2グループです。

sample.yaml
#------------------------------------------------------------------------------
# metadata
#------------------------------------------------------------------------------
Metadata:
  LICENSE: Apache License, Version 2.0
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: 'Input network information'
        Parameters:
          - VpcId
          - PublicSubnetId
          - EC2KeyPairName
          - WorkHostSecurityGroupCidr
          - WorkHostSecurityGroupCidrDescription
      - Label:
          default: 'Input work instance information'
        Parameters:
          - WorkHostName
          - WorkHostAmiOs
          - WorkHostAmiImageId
          - WorkHostInstanceType
          - GitUserName
          - GitUserEmail

パラメータ

ネットワーク関連のパラメータは、任意に指定できるようにし、OSには、「Amazon-Linux2-HVM」のAMIをデフォルト指定しています。
インスタンスタイプには、「t3.nano」をデフォルト指定しています。

sample.yaml
#------------------------------------------------------------------------------
# parameter
#------------------------------------------------------------------------------
Parameters: 
  #------------------------------------------------------------------------------
  # network information
  #------------------------------------------------------------------------------
  #-- Vpc
  VpcId:
    Type: String
    Default: ''
  #-- subnet
  PublicSubnetId:
    Type: String
    Default: ''
  #-- key pair
  EC2KeyPairName:
    Type: String
    Default: ''
  #-- security group cidr
  WorkHostSecurityGroupCidr:
    Type: String
    Default: ''
  #-- security group cidr description
  WorkHostSecurityGroupCidrDescription:
    Type: String
    Default: 'from limited'
  #------------------------------------------------------------------------------
  # work instance information
  #------------------------------------------------------------------------------
  #-- host name
  WorkHostName:
    Type: String
    Default: 'tmpwork-tokyo'
  #-- AMI
  WorkHostAmiOs:
    Type: String
    Default: 'Amazon-Linux2-HVM'
  WorkHostAmiImageId:
    Type: String
    Default: 'ami-011facbea5ec0363b'
  #-- instance type
  WorkHostInstanceType:
    Type: String
    Default: 't3.nano'
  #-- git user name
  GitUserName:
    Type: String
    Default: ''
  #-- git user email
  GitUserEmail:
    Type: String
    Default: ''

リソース

構成するリソースは、次の通りです

  • IAMロール設定
  • セキュリティグループ設定
  • EIP設定
  • EC2インスタンス設定
    • IAMロール
    • セキュリティグループ設定
  • EIP関連付け


サンプルコードを見る
sample.yaml
#------------------------------------------------------------------------------
# resource
#------------------------------------------------------------------------------
Resources:
  #------------------------------------------------------------------------------
  # IAM role
  #------------------------------------------------------------------------------
  WorkHostIamRole: 
    Type: "AWS::IAM::Role"
    #--- properties
    Properties:
      RoleName: !Sub '${WorkHostName}-role'
      Path: '/'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:   
          - 
            Action:   
            - "sts:AssumeRole"  
            Principal:   
              Service:   
              - "ec2.amazonaws.com"  
            Effect: 'Allow' 
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AWSCloudFormationFullAccess'
        - 'arn:aws:iam::aws:policy/IAMFullAccess'
        - 'arn:aws:iam::aws:policy/AmazonEC2FullAccess'
        - 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
        - 'arn:aws:iam::aws:policy/AWSLambdaFullAccess'
  #------------------------------------------------------------------------------
  # profile
  #------------------------------------------------------------------------------
  WorkHostInstanceProfile: 
    Type: "AWS::IAM::InstanceProfile"
    #--- properties
    Properties:
      Path: "/"
      Roles:
        - !Ref WorkHostIamRole
  #------------------------------------------------------------------------------
  # Security Group
  #------------------------------------------------------------------------------
  WorkHostSecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    #--- properties
    Properties:
      VpcId: !Sub "${VpcId}"
      GroupName: !Sub "${WorkHostName}-sg"
      GroupDescription: !Sub "${WorkHostName}-sg"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Sub "${WorkHostSecurityGroupCidr}"
          Description: !Sub "${WorkHostSecurityGroupCidrDescription}"
      Tags:
        - Key: 'Name'
          Value: !Sub "${WorkHostName}-sg"
  #------------------------------------------------------------------------------
  # Elastic IP
  #------------------------------------------------------------------------------
  WorkHostEIP:
    Type: "AWS::EC2::EIP"
    Properties:
      Domain: 'vpc'
      Tags:
        - Key: 'Name'
          Value: !Sub "${WorkHostName}-eip"
  #------------------------------------------------------------------------------
  # EC2 Instance
  #------------------------------------------------------------------------------
  WorkHostInstance:
    Type: "AWS::EC2::Instance"
    #--- metadata
    Metadata:
      AWS::CloudFormation::Init:
        configSets: 
          Install: 
            - "Install"
            - "AwsConfig"
            - "AwsCommand"
            - "GitConfig"
            - "GitCommand"
          Install:
          packages:
            yum:
              git: []
        AwsConfig:
          files:
            /home/ec2-user/.aws/config:
              content: !Sub |
                [default]
                region=${AWS::Region}
              mode: "000600"
              owner: 'ec2-user'
              group: 'ec2-user'
        AwsCommand:
          commands:
            dotaws_chown:
               command: 'chown ec2-user:ec2-user /home/ec2-user/.aws'
            dotaws_chmod:
               command: 'chmod 775 /home/ec2-user/.aws'
        GitConfig:
          files:
            /home/ec2-user/.gitconfig:
              content: !Sub |
                [user]
                name=${GitUserName}
                email=${GitUserEmail}
              mode: "000600"
              owner: 'ec2-user'
              group: 'ec2-user'
        GitCommand:
          commands:
            file_chown:
               command: 'chown ec2-user:ec2-user /home/ec2-user/.gitconfig'
            file_chmod:
               command: 'chmod 664 /home/ec2-user/.gitconfig'
    #--- properties
    Properties:
      ImageId: !Sub "${WorkHostAmiImageId}"
      InstanceType: !Sub "${WorkHostInstanceType}"
      IamInstanceProfile: !Ref WorkHostInstanceProfile
      SubnetId: !Sub "${PublicSubnetId}"
      SecurityGroupIds:
        - !Ref WorkHostSecurityGroup
      KeyName: !Sub "${EC2KeyPairName}"
      Tags:
        - Key: 'Name'
          Value: !Sub "${WorkHostName}01"
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WorkHostInstance --configsets Install --region ${AWS::Region}
  #------------------------------------------------------------------------------
  # associate public ip
  #------------------------------------------------------------------------------
  WorkHostEIPAssociate:
    Type: "AWS::EC2::EIPAssociation"
    #--- properties
    Properties: 
      AllocationId: !GetAtt WorkHostEIP.AllocationId
      InstanceId: !Ref WorkHostInstance


スタックの登録

事前作業

手動対応をあらかじめ実施します

  • VPCの構築
  • サブネットの構築
    • インターネットと通信できるサブネット(IGWがアタッチされるサブネット)
  • キーペアの設定
    • sshログインの鍵

マネージドコンソールにテンプレートをアップロードして実行

「スタックの作成」>「新しいリソースを使用(標準)」を選択

screenshot-ap-northeast-1.console.aws.amazon.com-2020.01.31-12_20_54.png

テンプレートを指定してアップロード

screenshot-ap-northeast-1.console.aws.amazon.com-2020.01.31-12_24_42.png

パラメータ入力

スタック名、VpcId、PublicSubnetId、EC2KeyPairName、WorkHostSecurityGroupCidrをそれぞれ入力します
screenshot-ap-northeast-1.console.aws.amazon.com-2020.01.31-12_28_34.png

スタックオプションの設定

タグ、アクセス許可とも特に指定しません
screenshot-ap-northeast-1.console.aws.amazon.com-2020.01.31-14_05_48.png

詳細オプション

スタックポリシーは、デフォルト「スタックポリシーなし」のまま
ロールバック設定、通知オプションとも特に指定しません
スタック作成オプションは、失敗時のロールバック・削除保護ともデフォルトのまま
必要がありましたら適時変更ください

screenshot-ap-northeast-1.console.aws.amazon.com-2020.01.31-14_06_34.png

screenshot-ap-northeast-1.console.aws.amazon.com-2020.01.31-14_07_06.png

レビュー {スタック名}

指定した内容の確認フォームとなります

今回テンプレートには、「AWS::IAM::Role」が含まれるため、下記の確認が表示されます
チェックして次に進みます
screenshot-ap-northeast-1.console.aws.amazon.com-2020.01.31-14_13_52.png

スタックのステータス

テンプレートに記載された内容で構成が開始されたらイベント情報でスタックのステータスが確認できます
screenshot-ap-northeast-1.console.aws.amazon.com-2020.01.31-14_17_09.png

スタック名のステータスが「CREATE_COMPLETE」になれば、完了です。

はまったこと・悩んだこと

  • EC2インスタンス内のパッケージインストールやファイル操作

メモ・考察

  • スタックの削除でテンプレートから構成されたリソースがすべて削除されるので安心してリソース削除が行える
    • 削除確認を促す場合は、削除保護チェックをオンにすると良い
  • 簡素な構成であってもリソース起動・削除が安価になった

参考

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