Closed32

AWS Hands-on for Beginners AWS 環境のコード管理 AWS CloudFormationで Web システムを構築する

ito_110ito_110

1:ハンズオンの概要

ハンズオンの概要

AWS CloudFormation初心者向けの講座
全体で1時間程度

ゴール

  • クラウドにおける構成管理の考え方を理解
  • CloudFormationの手法を学習

アジェンダ

  • Cloudformation概要
  • テンプレの作成
  • VPC作成
  • EC2作成
  • RDS・ELB作成
  • 環境削除

コードで管理する理由-

  • 再現性
  • 簡単に複製可能
  • ワークロード全体の品質担保
  • 手作業では人為的ミス発生・対応への一貫性への懸念

Well-Archeted フレームワーク

AWSのいつもの。メモは省略。

ito_110ito_110

コードを使った運用のポイント

  1. コードで全ての構成を定義
    同じ環境を迅速に繰り返し作成可能
  2. イベントに対してスクリプトで対処
    自動的に、同じ処理を繰り返し実施可能
  3. アプリケーションと同じ手法でコードを開発
    コードと作成した環境の品質を担保
ito_110ito_110

2:CloudFormation概要

  • AWS環境のコードによる管理を実現
  • テンプレートで定義する
  • 基本機能:作成・変更:削除
ito_110ito_110

テンプレート

  • CloudFormationの心臓部でスタックの設計図
  • JSON・YAML形式でスタックの情報を記載
  • 定義された構成を並列で作成し、リソースに依存関係がある場合はCloudFormationが自動的に解決する

テンプレートの内容

  • Resources:EC2やRDSなど起動するリソースを指定
  • Format:「2010-09-09」のみ
  • Description:テンプレートの説明について記述
  • Parameters:スタック構築時にユーザーに指定させる値
  • Outputs:スタック構築後に取得・表示したい情報の定義
ito_110ito_110

スタック

  • 単一のユニットとして管理できるAWSリソースのコレクション
  • スタック単位でリソースの管理が可能
  • リソースの構築順は、CloudFormationが自動的に決定
ito_110ito_110

Cloud9構築

  • 東京リージョン
  • 設定は全てデフォルトで構築

初期設定

  • 左上の「C9」ロゴから「Preferences」を選択
  • 「soft tabs」を「4」から「2」へ
ito_110ito_110
  • AWSのバージョンをターミナルから確認
aws --version
  • CloudFormationのヘルプを確認
    スペースで読み進め、qで退出
    UserGuideと併用して内容を確認
aws cloudformation help
ito_110ito_110

公式配布資料:3_開発環境の構築

環境の確認

aws --version
aws cloudformation help
aws cloudformation describe-stacks help

aws cli のためのコマンド補完設定

echo "complete -C '/usr/local/bin/aws_completer' aws" >> ~/.bashrc
source ~/.bashrc
ito_110ito_110

4:テンプレートの実行方法・VPCの作成

今回のハンズオンはEC2/RDS 1台の構成

ito_110ito_110

スタックの操作

  • AWS マネジメントコンソール (今回のハンズオン)
  • AWS CLI
  • 各種SDK
ito_110ito_110

スタックを作成

  • AWSコンソールからCloudFormationへ
  • 新しいスタックの作成>新しいリソースを選択
  • 配布された「vpc.yaml」を選択
  • 名前はhandson-cfn
  • 基本的に設定はデフォルト
ito_110ito_110

エラー発生:スタック作成できない

やろうとしたこと

CloudFormationでスタック作成

発生したエラー

エラーメッセージ
Resource handler returned message: "The maximum number of internet gateways has been reached. (Service: Ec2, Status Code: 400, Request ID: cd5476b4-25bf-45b8-a557-e6fdccc3c597)" (RequestToken: 38470b1b-e332-01b8-d2a7-23a6b8eb2532, HandlerErrorCode: ServiceLimitExceeded)

VPCが上限であることが原因らしい
不必要なVPCを削除して再度トライ

ito_110ito_110

テンプレートを編集


01_vpc.ymlをc9で開き、valueに:updateを追記する

ito_110ito_110

テンプレートより更新

AWS-CLIを利用

# ディレクトリを移動
cd cfn
# validate
aws cloudformation validate-template --template-body file://01_vpc.yml
# update
aws cloudformation update-stack --stack-name handson-cfn --template-body file://01_vpc.yml
ito_110ito_110

5:EC2の作成_1

下記を実施

  • EC2用のスタック作成
  • テンプレートの編集
ito_110ito_110

公式が事前に配布しているec2.yml

ec2.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for EC2

Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:
  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro

Outputs:
  EC2WebServer01:
    Value: !Ref EC2WebServer01
    Export:
      Name: !Sub ${AWS::StackName}-EC2WebServer01


ito_110ito_110

cloudformationスタックを作成

aws cloudformation create-stack --stack-name handson-vpc-ec2 --template-body file://cfn/02_ec2.yml
ito_110ito_110

テンプレートを編集

サブネットIDを追記

02_ec2.yml
〜
Resources:
  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro
      SubnetId: subnet-01a0b7223fb471e64 # 追記
〜

ito_110ito_110

ユーザーデータを追加

  • 組み込み関数!Base64を使用する
02_ec2.yml
      UserData: !Base64 |
        #! /bin/bash
        yum update -y
        amazon-linux-extras install php7.2 -y
        yum -y install mysql httpd php-mbstring php-xml
        
        wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
        tar zxvf /tmp/latest-ja.tar.gz -C /tmp
        cp -r /tmp/wordpress/* /var/www/html/
        touch /var/www/html/.check_alive
        chown apache:apache -R /var/www/html
        
        systemctl enable httpd.service
        systemctl start httpd.service

ito_110ito_110

下記コマンド実行

terminal
aws cloudformation validate-template --template-body file://cfn/02_ec2.yml
aws cloudformation update-stack --stack-name handson-vpc-ec2 --template-body file://cfn/02_ec2.yml
ito_110ito_110
02_ec2.yml
      UserData: !Base64 |
        #! /bin/bash
        yum update -y
        amazon-linux-extras install php7.2 -y
        yum -y install mysql httpd php-mbstring php-xml
        
        wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
        tar zxvf /tmp/latest-ja.tar.gz -C /tmp
        cp -r /tmp/wordpress/* /var/www/html/
        touch /var/www/html/.check_alive
        chown apache:apache -R /var/www/html
        
        systemctl enable httpd.service
        systemctl start httpd.service

# 下記を追記
      SecurityGroupIds:
        - !Ref EC2SG
  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: sg for web server
      VpcId: vpc-093af4a39d72aa99c
      SecurityGroupIngress: 
        - IpProtocol: tcp
          CidrIp: 10.0.0.0/16
          FromPort: 80
          ToPort: 80
ito_110ito_110

7:RDS, ELBの作成、スタックのライフサイクル・分割

elb.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for ALB

Parameters:
  VPCStack:
    Type: String
    Default: handson-vpc
  EC2Stack:
    Type: String
    Default: handson-vpc-ec2

Resources:
  FrontLB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Ref AWS::StackName
      Subnets:
        - Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet1
        - Fn::ImportValue: !Sub ${VPCStack}-PublicSubnet2
      SecurityGroups: 
        - !Ref SecurityGroupLB

  FrontLBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref FrontLB
      Port: 80
      Protocol: HTTP 
      DefaultActions: 
        - Type: forward
          TargetGroupArn: !Ref FrontLBTargetGroup

  FrontLBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-tg
      VpcId:
        Fn::ImportValue: !Sub ${VPCStack}-VPCID
      Port: 80
      Protocol: HTTP
      HealthCheckPath: /.check_alive
      Targets:
        - Id:
            Fn::ImportValue: !Sub ${EC2Stack}-EC2WebServer01

  SecurityGroupLB:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: !Ref AWS::StackName
      VpcId:
        Fn::ImportValue: !Sub ${VPCStack}-VPCID
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

Outputs:
  FrontLBEndpoint:
    Value: !GetAtt FrontLB.DNSName
    Export:
      Name: !Sub ${AWS::StackName}-Endpoint


ito_110ito_110
rds.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for RDS

Parameters:
  VPCStack:
    Type: String
    Default: handson-vpc
  DBUser:
    Type: String
    Default: dbmaster
  DBPassword:
    Type: String
    Default: H&ppyHands0n
    NoEcho: true

  
Resources:
  DBInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Delete
    Properties:
      DBInstanceClass: db.t2.micro
      AllocatedStorage: "10"
      StorageType: gp2
      Engine: MySQL
      MasterUsername: !Ref DBUser
      MasterUserPassword: !Ref DBPassword
      DBName: wordpress
      BackupRetentionPeriod: 0
      DBSubnetGroupName: !Ref DBSubnetGroup
      VPCSecurityGroups:
        - !Ref DBSecurityGroup

  DBSubnetGroup: 
    Type: AWS::RDS::DBSubnetGroup
    Properties: 
      DBSubnetGroupDescription: DB Subnet Group for Private Subnet
      SubnetIds: 
        - Fn::ImportValue: !Sub ${VPCStack}-PrivateSubnet1
        - Fn::ImportValue: !Sub ${VPCStack}-PrivateSubnet2

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: !Sub ${AWS::StackName}-MySQL
      VpcId:
        Fn::ImportValue: !Sub ${VPCStack}-VPCID
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 10.0.0.0/16


Outputs:
  DBEndpoint:
    Value: !GetAtt DBInstance.Endpoint.Address
    Export:
      Name: !Sub ${AWS::StackName}-DBEndpoint

このスクラップは2022/08/05にクローズされました