

# CloudFormation のスタックを更新する
<a name="updating.stacks.walkthrough"></a>

**注記**  
このチュートリアルは、[Amazon EC2 にアプリケーションをデプロイする](deploying.applications.md) チュートリアルでの概念に基づいています。そのチュートリアルを完了していない場合は、まず CloudFormation による EC2 ブートストラップを理解することをお勧めします。

このトピックでは、実行中のスタックの更新のシンプルな進行過程を示します。以下の手順について説明します。

1. **初期スタックを作成する** — 基本の Amazon Linux 2 AMI を使用してスタックを作成し、CloudFormation ヘルパースクリプトを使用して Apache Web Server とシンプルな PHP アプリケーションをインストールします。

1. **アプリケーションを更新する** - アプリケーション内のファイルのいずれかを更新し、CloudFormation を使用してソフトウェアをデプロイします。

1. **キーペアを追加する** - インスタンスに Amazon EC2 キーペアを追加し、セキュリティグループを更新して、インスタンスへの SSH アクセスを可能にします。

1. **インスタンスタイプを追加する** - 基盤となる Amazon EC2 インスタンスのインスタンスタイプを変更します。

1. **AMI を更新する** - スタック内の Amazon EC2 インスタンスの Amazon マシンイメージ (AMI) を変更します。

**注記**  
CloudFormation は無料で使用できますが、作成した Amazon EC2 リソースに対しては課金されます。ただし、AWS を初めて使用する場合は、 [無料利用枠](https://aws.amazon.com/free/)を利用して、この学習プロセス中のコストを最小に抑えるか無料にできます。

**Topics**
+ [ステップ 1: 初期スタックを作成する](#update-stack-initial-stack)
+ [ステップ 2: アプリケーションを更新する](#update-stack-update-application)
+ [ステップ 3: キーペアを使用して SSH アクセスを追加する](#update-stack-add-key-pair)
+ [ステップ 4: インスタンスタイプを更新する](#update-stack-update-instance-type)
+ [ステップ 5: AMI を更新する](#update-stack-update-ami)
+ [アベイラビリティーと影響に関する検討事項](#update.walkthrough.impact)
+ [関連リソース](#update.walkthrough.related)

## ステップ 1: 初期スタックを作成する
<a name="update-stack-initial-stack"></a>

まず、このトピック全体で使用するスタックを作成することから開始します。Apache Web Server でホストされ Amazon Linux 2 AMI 上で実行される単一のインスタンス PHP ウェブアプリケーションを起動する単純なテンプレートが用意されています。

Apache Web Server、PHP、および単純な PHP アプリケーションはすべて、Amazon Linux 2 AMI にデフォルトでインストールされている CloudFormation ヘルパースクリプトによってインストールされます。以下のテンプレートスニペットには、インストールするパッケージとファイルを記述するメタデータが表示されています。この場合は、Amazon Linux 2 AMI の Yum リポジトリからの Apache Web Server と PHP 実行環境です。またこのスニペットには、Apache Web Server の実行を確認する `Services` セクションが含まれています。

```
WebServerInstance:
  Type: AWS::EC2::Instance
  Metadata:
    AWS::CloudFormation::Init:
      config:
        packages:
          yum:
            httpd: []
            php: []
        files:
          /var/www/html/index.php:
            content: |
              <?php
              echo '<h1>Hello World!</h1>';
              ?>
            mode: '000644'
            owner: apache
            group: apache
        services:
          systemd:
            httpd:
              enabled: true
              ensureRunning: true
```

アプリケーション自体は「Hello World」サンプルであり、その全体がテンプレート内で定義されています。実際のアプリケーションでは、ファイルは Amazon S3、GitHub、その他のリポジトリに格納され、テンプレートから参照されます。CloudFormation はパッケージ (RPM や RubyGems など) をダウンロードし、個別のファイルを参照して `.zip` や `.tar` ファイルを解凍することで、Amazon EC2 インスタンス上にアプリケーションの中間生成物を作成することができます。

テンプレートは `cfn-hup` デーモンを有効化して構成し、Amazon EC2 インスタンスのメタデータ内で定義された構成への変更をリッスンします。`cfn-hup` デーモンを使用することで、Apache や PHP のバージョンなどのアプリケーションソフトウェアを更新したり、または CloudFormation から PHP アプリケーションファイル自体を更新したりできます。テンプレート内の同じ Amazon EC2 リソースからの次のスニペットは、2 分ごとに `cfn-init` を呼び出してメタデータに更新を通知および適用するように `cfn-hup` を設定するために必要な部分を示しています。それ以外の場合、`cfn-init` は起動時に 1 回だけ実行されます。

```
files:
  /etc/cfn/cfn-hup.conf:
    content: !Sub |
      [main]
      stack=${AWS::StackId}
      region=${AWS::Region}
      # The interval used to check for changes to the resource metadata in minutes. Default is 15
      interval=2
    mode: '000400'
    owner: root
    group: root
  /etc/cfn/hooks.d/cfn-auto-reloader.conf:
    content: !Sub |
      [cfn-auto-reloader-hook]
      triggers=post.update
      path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init
      action=/opt/aws/bin/cfn-init -s ${AWS::StackId} -r WebServerInstance --region ${AWS::Region}
      runas=root
services:
  systemd:
    cfn-hup:
      enabled: true
      ensureRunning: true
      files:
        - /etc/cfn/cfn-hup.conf
        - /etc/cfn/hooks.d/cfn-auto-reloader.conf
```

スタックを完了するには、Amazon EC2 インスタンス定義の `Properties` セクションで、`UserData` プロパティに、パッケージとファイルをインストールするために `cfn-init` を呼び出す `cloud-init` スクリプトが含まれています。詳細については、「*CloudFormation テンプレートリファレンスガイド*」の「[CloudFormation ヘルパースクリプトリファレンス](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/cfn-helper-scripts-reference.html)」を参照してください。テンプレートは Amazon EC2 セキュリティグループも作成します。

```
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  LatestAmiId:
    Description: The latest Amazon Linux 2 AMI from the Parameter Store
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'

  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.nano
      - t3.micro
      - t3.small
      - t3.medium
      - t3a.nano
      - t3a.micro
      - t3a.small
      - t3a.medium
      - m5.large
      - m5.xlarge
      - m5.2xlarge
      - m5a.large
      - m5a.xlarge
      - m5a.2xlarge
      - c5.large
      - c5.xlarge
      - c5.2xlarge
      - r5.large
      - r5.xlarge
      - r5.2xlarge
      - r5a.large
      - r5a.xlarge
      - r5a.2xlarge
    ConstraintDescription: must be a valid EC2 instance type.
    
Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          # Get the latest CloudFormation package
          yum update -y aws-cfn-bootstrap
          # Run cfn-init
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region} || error_exit 'Failed to run cfn-init'        
          # Start up the cfn-hup daemon to listen for changes to the EC2 instance metadata
          /opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'
          # Signal success or failure
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region}
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
              php: []
          files:
            /var/www/html/index.php:
              content: |
                <?php
                echo "<h1>Hello World!</h1>";
                ?>
              mode: '000644'
              owner: apache
              group: apache
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                # The interval used to check for changes to the resource metadata in minutes. Default is 15
                interval=2
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -s ${AWS::StackId} -r WebServerInstance --region ${AWS::Region}
                runas=root
          services:
            systemd:
              httpd:
                enabled: true
                ensureRunning: true
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M

  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

Outputs:
  WebsiteURL:
    Value: !Sub 'http://${WebServerInstance.PublicDnsName}'
    Description: URL of the web application
```

**このテンプレートからスタックを起動するには**

1. テンプレートをコピーし、システム上にローカルにテキストファイルとして保存します。このファイルは後続の手順で必要となるため、保存場所をメモしておいてください。

1. AWS マネジメントコンソール にサインインし、CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. **[スタックを作成する]** を選択し、[新しいリソースの使用 (標準)] を選択します。

1. **[既存のテンプレートを選択する]** を選択します。

1. **[テンプレートを指定する]** で、**[テンプレートファイルをアップロードする]** を選択し、最初のステップで作成したファイルを参照し、**[次へ]** を選択します。

1. **[スタックの詳細を指定する]** ページで、[スタック名] として **UpdateTutorial** を入力します。

1. **[パラメータ]** で、すべてのパラメータを同じに保ち、**[次へ]** を 2 回選択します。

1. **[確認して作成]** 画面で、**[送信]** を選択します。

スタックのステータスが `CREATE_COMPLETE` に変更された後、**[出力]** タブにウェブサイトの URL が表示されます。`WebsiteURL` 出力の値を選択した場合、新しい PHP アプリケーションが実行されていることを確認できます。

## ステップ 2: アプリケーションを更新する
<a name="update-stack-update-application"></a>

スタックをデプロイしたので、今度はアプリケーションを更新してみましょう。アプリケーションによって出力されるテキストに簡単な変更を加えます。以下のテンプレートスニペットに示したように、index.php ファイルに echo コマンドを追加します。

```
files:
  /var/www/html/index.php:
    content: |
      <?php
      echo "<h1>Hello World!</h1>";
      {{echo "<p>This is an updated version of our application.</p>";}}
      ?>
    mode: '000644'
    owner: apache
    group: apache
```

テキストエディタを使用して、ローカルに保存したテンプレートファイルを手動で編集します。

次に、スタックを更新します。

**更新されたテンプレートでスタックを更新するには**

1. CloudFormation コンソールで、**UpdateTutorial** スタックを選択します。

1. **[更新]、[直接更新を実行]** を選択します。

1. **[既存のテンプレートを置き換える]** を選択します。

1. **[テンプレートを指定する]** で、**[テンプレートファイルをアップロードする]** を選択し、変更したテンプレートをアップロードしてから、**[次へ]** を選択します。

1. **[スタックの詳細を指定する]** ページで、すべてのパラメータを同じに保持し、**[次へ]** を選択します。

1. **[確認]** ページで変更内容を確認します。**[変更]**で、CloudFormation が `WebServerInstance` リソースを更新することがわかります。

1. [**Submit**] を選択してください。

スタックの状態が `UPDATE_COMPLETE` になったら、`WebsiteURL` の出力値を再度選択して、アプリケーションに対する変更が反映されていることを確認できます。`cfn-hup` デーモンが 2 分間隔で実行されます。そのため、スタックが更新されてからアプリケーションが変更されるまでに最大 2 分程度かかる場合があります。

更新された一連のリソースを確認するには、CloudFormation コンソールを使用します。[**イベント**] タブでスタックイベントに注目してください。この場合は、Amazon EC2 インスタンスのメタデータ `WebServerInstance` が更新されます。また CloudFormation によって他のリソース (`WebServerSecurityGroup`) も再評価され、ほかに変更がないことが確認されます。他のスタックリソースは変更されませんでした。CloudFormation によって更新されるスタック内のリソースは、そのスタックに対する変更の影響を受けるリソースだけです。そうした変更には、プロパティやメタデータの変更など直接的なものもあれば、`Ref`、`GetAtt` など、組み込みテンプレート関数を介したデータフローや依存関係に起因するものもあります。詳細については、「[組み込み関数リファレンス](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/intrinsic-function-reference.html)」を参照してください。

このシンプルな更新は、プロセスを示しています。ただし、Amazon EC2 インスタンスにデプロイするファイルやパッケージに対し、さらに複雑な変更を行うこともできます。たとえば、インスタンスに MySQL を追加しなければならなくなったとします。MySQL の PHP サポートも必要です。そのための作業は単に、追加サービスと併せて、必要なパッケージとファイルを構成に追加するだけです。そのうえでスタックを更新して変更をデプロイすることになります。

```
packages:
  yum:
    httpd: []
    php: []
    {{mysql: []}}
    {{php-mysql: []}}
    {{mysql-server: []}}
    {{mysql-libs: []}}

  {{...}}

services:
  systemd:
    httpd:
      enabled: true
      ensureRunning: true
    cfn-hup:
      enabled: true
      ensureRunning: true
      files:
        - /etc/cfn/cfn-hup.conf
        - /etc/cfn/hooks.d/cfn-auto-reloader.conf
    {{mysqld:}}
      {{enabled: true}}
      {{ensureRunning: true}}
```

CloudFormation のメタデータを更新して、アプリケーションで使用するパッケージを新しいバージョンに更新できます。これまでの例では、各パッケージのバージョンプロパティが空になっています。この場合、`cfn-init` によって最新バージョンのパッケージがインストールされます。

```
packages:
  yum:
    httpd: []
    php: []
```

必要であれば、パッケージのバージョン文字列を指定することもできます。以降のスタック更新要求でバージョン文字列を変更した場合、その新しいバージョンのパッケージがデプロイされます。以下に示したのは、RubyGems パッケージのバージョン番号を使用した例です。バージョニングをサポートするパッケージはすべて、特定のバージョンを持つことができます。

```
packages:
  rubygems:
    mysql: []
    rubygems-update:
      - "1.6.2"
    rake:
      - "0.8.7"
    rails:
      - "2.3.11"
```

## ステップ 3: キーペアを使用して SSH アクセスを追加する
<a name="update-stack-add-key-pair"></a>

テンプレートのリソースを更新して、テンプレート内で元々指定されていなかったプロパティを追加することもできます。これについて学ぶため、Amazon EC2 キーペアを既存の EC2 インスタンスに追加し、Amazon EC2 セキュリティグループでポート 22 を開きます。これにより、Secure Shell (SSH) を使用してインスタンスにアクセスできるようになります。

**既存の Amazon EC2 インスタンスに SSH アクセスを追加するには**

1. 既存の Amazon EC2 キーペアおよび SSH ロケーションの名前を渡すため、テンプレートに 2 つのパラメーターを追加します。

   ```
   Parameters:
     KeyName:
       Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
       Type: AWS::EC2::KeyPair::KeyName
       ConstraintDescription: must be the name of an existing EC2 KeyPair.
   
     SSHLocation:
       Description: The IP address that can be used to SSH to the EC2 instances in CIDR format (e.g. 203.0.113.1/32)
       Type: String
       MinLength: 9
       MaxLength: 18
       Default: 0.0.0.0/0
       AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$'
       ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
   ```

1. Amazon EC2 インスタンスに `KeyName` プロパティを追加します。

   ```
   WebServerInstance:
     Type: AWS::EC2::Instance
     Properties:
       ImageId: !Ref LatestAmiId
       InstanceType: !Ref InstanceType
       KeyName: !Ref KeyName
       SecurityGroupIds:
         - !Ref WebServerSecurityGroup
   ```

1. Amazon EC2 セキュリティグループの Ingress ルールに、ポート 22 と SSH ロケーションを追加します。

   ```
   WebServerSecurityGroup:
     Type: AWS::EC2::SecurityGroup
     Properties:
       GroupDescription: Enable HTTP access via port 80 and SSH access via port 22
       SecurityGroupIngress:
         - IpProtocol: tcp
           FromPort: 80
           ToPort: 80
           CidrIp: 0.0.0.0/0
         - IpProtocol: tcp
           FromPort: 22
           ToPort: 22
           CidrIp: !Ref SSHLocation
   ```

1. 「[ステップ 2: アプリケーションを更新する](#update-stack-update-application)」で説明されているのと同じステップを使用してスタックを更新します。

## ステップ 4: インスタンスタイプを更新する
<a name="update-stack-update-instance-type"></a>

次に、インスタンスタイプを変更して、基盤となるインフラストラクチャを更新する方法を示しましょう。

ここまでで構築したスタックは、t3.micro Amazon EC2 インスタンスを使用します。例として、新しく作成したウェブサイトに、t3.micro インスタンスで処理できる以上のトラフィックが発生しているとします。このため、m5.large Amazon EC2 インスタンスタイプに移行する必要が生じました。インスタンスタイプのアーキテクチャーが変わると、異なる AMI でインスタンスが作成される必要があります。ただし、t3.micro と m5.large の両方は同じ CPU アーキテクチャを使用し、Amazon Linux 2 (x86\_64) AMI を実行します。詳細については、*Amazon EC2 ユーザーガイド*の[インスタンスタイプ変更の互換性](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/resize-limitations.html)を参照してください。

前のステップで編集したテンプレートを使用して、インスタンスタイプを変更しましょう。`InstanceType` はテンプレートへの入力パラメータであるため、テンプレートを変更する必要はありません。**[スタックの詳細を指定する]** ページでパラメータの値を変更できます。

**スタックを新しいパラメータ値で更新するには**

1. CloudFormation コンソールで、**UpdateTutorial** スタックを選択します。

1. **[更新]、[直接更新を実行]** を選択します。

1. **[既存のテンプレート使用する]** を選択し、**[次へ]** を選択します。

1. **[スタックの詳細を指定する]** ページで、**InstanceType** テキストボックスの値を `t3.micro` から `m5.large` に変更します。次に、**[次へ]** を 2 回選択します。

1. **[確認]** ページで変更内容を確認します。**[変更]**で、CloudFormation が `WebServerInstance` リソースを更新することがわかります。

1. [**Submit**] を選択してください。

インスタンスを起動および停止することで、EBS-backed Amazon EC2 インスタンスのインスタンスタイプを動的に変更できます。CloudFormation は、インスタンスタイプを更新してインスタンスを再起動することで変更を最適化しようとします。そのため、インスタンス ID は変更されません。ただしインスタンスが再開されると、インスタンスのパブリック IP アドレスは変更されます。変更後に Elastic IP アドレスが正しくバインドされるよう、CloudFormation は Elastic IP アドレスも更新します。CloudFormation コンソールの **[イベント]** タブで変更を見ることができます。

AWS マネジメントコンソール からインスタンスタイプを調べるには、Amazon EC2 コンソールを開き、インスタンスを探します。

## ステップ 5: AMI を更新する
<a name="update-stack-update-ami"></a>

次に、Amazon Linux の次世代である Amazon Linux 2023 を使用するようにスタックを更新しましょう。

AMI の更新は、インスタンスの置き換えを必要とする大幅な変更です。単純にインスタンスの開始と停止によって AMI を変更することはできません。このような変更は、CloudFormation によって不変のリソースプロパティに対する変更とみなされます。不変のプロパティに変更を加える場合、CloudFormation は、代替リソース (このケースでは、新しい AMI を実行する新しい Amazon EC2 インスタンス) を起動する必要があります。

Amazon Linux 2023 を使用するために、スタックテンプレートを更新する方法を見てみましょう。主な変更には、AMI パラメータの更新と、`yum` から `dnf` パッケージマネージャーへの変更が含まれます。

```
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  LatestAmiId:
    Description: The latest Amazon Linux 2023 AMI from the Parameter Store
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64'

  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.nano
      - t3.micro
      - t3.small
      - t3.medium
      - t3a.nano
      - t3a.micro
      - t3a.small
      - t3a.medium
      - m5.large
      - m5.xlarge
      - m5.2xlarge
      - m5a.large
      - m5a.xlarge
      - m5a.2xlarge
      - c5.large
      - c5.xlarge
      - c5.2xlarge
      - r5.large
      - r5.xlarge
      - r5.2xlarge
      - r5a.large
      - r5a.xlarge
      - r5a.2xlarge
    ConstraintDescription: must be a valid EC2 instance type.

  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.

  SSHLocation:
    Description: The IP address that can be used to SSH to the EC2 instances in CIDR format (e.g. 203.0.113.1/32)
    Type: String
    MinLength: 9
    MaxLength: 18
    Default: 0.0.0.0/0
    AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$'
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
    
Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: !Ref InstanceType
      KeyName: !Ref KeyName
      SecurityGroupIds:
        - !Ref WebServerSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          # Get the latest CloudFormation package
          dnf update -y aws-cfn-bootstrap
          # Run cfn-init
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region} || error_exit 'Failed to run cfn-init'        
          # Start up the cfn-hup daemon to listen for changes to the EC2 instance metadata
          /opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'
          # Signal success or failure
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region}
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            dnf:
              httpd: []
              php: []
          files:
            /var/www/html/index.php:
              content: |
                <?php
                echo "<h1>Hello World!</h1>";
                echo "<p>This is an updated version of our application.</p>";
                echo "<p>Running on Amazon Linux 2023!</p>";
                ?>
              mode: '000644'
              owner: apache
              group: apache
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                # The interval used to check for changes to the resource metadata in minutes. Default is 15
                interval=2
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -s ${AWS::StackId} -r WebServerInstance --region ${AWS::Region}
                runas=root
          services:
            systemd:
              httpd:
                enabled: true
                ensureRunning: true
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M

  WebServerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable HTTP access via port 80 and SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation

Outputs:
  WebsiteURL:
    Value: !Sub 'http://${WebServerInstance.PublicDnsName}'
    Description: URL of the web application
```

「[ステップ 2: アプリケーションを更新する](#update-stack-update-application)」で説明されているのと同じステップを使用してスタックを更新します。

新しいインスタンスが実行状態になった後、CloudFormation は、スタック内の他のリソースが新しいリソースを指し示すように更新します。新しいリソースがすべて作成されると、古いリソースは削除されます。このプロセスを `UPDATE_CLEANUP` といいます。更新後、スタック内のインスタンスの ID とアプリケーション URL が変わっています。**[イベント]** テーブル内のイベントには、「Requested update has a change to an immutable property and hence creating a new physical resource」という説明が表示され、リソースが置き換えられたことがわかります。

別の方法として: 更新対象の AMI に組み込むアプリケーションコードを記述した場合、同じスタック更新メカニズムを使用して AMI を更新し、新しいアプリケーションをロードすることができます。

**カスタムアプリケーションコードを使用して AMI を更新するには**

1. アプリケーションまたはオペレーティング システムの変更を含んだ新しい AMI を作成します。詳細については、「*Amazon EC2 ユーザーガイド*」の「[Amazon EBS-backed AMI の作成](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html)」を参照してください。

1. テンプレートに新しい AMI ID を追加します。

1. 「[ステップ 2: アプリケーションを更新する](#update-stack-update-application)」で説明されているのと同じステップを使用してスタックを更新します。

スタックが更新されると、AMI ID が変更されたことを CloudFormation が検出し、先ほどと同じようにスタックの更新を開始します。

## アベイラビリティーと影響に関する検討事項
<a name="update.walkthrough.impact"></a>

プロパティによって、スタック内のリソースに異なる影響が及ぼされます。CloudFormation を使用してあらゆるプロパティを更新できますが、変更を加える前に、以下の点について検討する必要があります。

1. アップデートによって、リソース自体にどのような影響が与えられるか。たとえば、アラームのしきい値を変更すると、アップデート中にアラームが非アクティブになります。前述の通り、インスタンスタイプを変更するには、インスタンスをいったん停止して再開する必要があります。CloudFormation は、基盤となるリソースの更新または変更アクションを使用して、リソースを変更します。アップデートの影響を理解するには、特定のリソースのドキュメントを参照してください。

1. 変更は可変か不変か。Amazon EC2 インスタンスでの AMI の変更など、リソースプロパティへの変更のタイプによっては、基盤となるサービスにサポートされていない場合があります。可変の変更の場合、CloudFormation は、基盤となるリソースの Update または Modify タイプの API を使用します。不変のプロパティの変更の場合、CloudFormation は、アップデートされたプロパティを使用して新しいリソースを作成し、古いリソースを削除する前にそれらをスタックにリンクします。CloudFormation はスタックリソースのダウンタイムを削減しようとしますが、リソースは複数のステップが必要な処理であり、ある程度の時間がかかります。スタックの再構成中、アプリケーションは完全には機能しません。たとえば、要求への応答や、データベースへのアクセスができない可能性があります。

## 関連リソース
<a name="update.walkthrough.related"></a>

CloudFormation を使用してアプリケーションを開始する方法と、Puppet や Opscode Chef のようなその他の構成やデプロイメントサービスと統合する方法については、以下のホワイトペーパーをご参照ください。
+ [CloudFormation によるアプリケーションのブートストラップ](https://s3.amazonaws.com/cloudformation-examples/BoostrappingApplicationsWithAWSCloudFormation.pdf)
+ [CloudFormation と Opscode Chef の統合](https://s3.amazonaws.com/cloudformation-examples/IntegratingAWSCloudFormationWithOpscodeChef.pdf)
+ [CloudFormation と Puppet の統合](https://s3.amazonaws.com/cloudformation-examples/IntegratingAWSCloudFormationWithPuppet.pdf)