nginxインストールシェルをS3に配置してEC2インスタンスで実行

## はじめに
先日nginxでWebサーバーを構築しました。応用としてnginxをインストールするためのシェルスクリプトをS3バケットに配置、EC2インスタンスのユーザーデータでS3バケットからコピー&実行して自動的にnginxをインストールされるようにテンプレートも修正しました。

## インストール実行シェル
以下シェルをS3バケットに配置しています。
```
#!/bin/bash
sudo amazon-linux-extras install nginx1 -y
sudo systemctl start nginx
sudo systemctl enable nginx

# ヘルスチェック用のHTMLファイルをドキュメントルートに作成
echo "<html><body>OK</body></html>" | sudo tee /usr/share/nginx/html/health
```

## EC2テンプレート
### 変更点
- IAMロール:EC2インスタンスが使用するIAMロールを作成し、S3バケットからオブジェクトを取得する権限を付与。
- インスタンスプロファイル:IAMロールをインスタンスプロファイルにアタッチし、EC2インスタンスにアタッチ
- ユーザーデータ:EC2インスタンスの起動時に、ユーザーデータで指定されたシェルスクリプトを実行。このスクリプトはS3バケットからコピーされ、インスタンス内で実行される。
```
AWSTemplateFormatVersion: 2010-09-09
Description: template to launch an EC2 instance

Parameters:
  VPCStack:
    Type: String
    Description: test-vpc
    Default: test-vpc
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
  Prefix:
    Type: String
    
  UserDataBucket:
    Type: String
    
  UserDataShell:
    Type: String

Resources:
  EC2IAMRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${Prefix}-ec2-role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        -
          PolicyName: !Sub "${Prefix}-ec2-policy"
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              -
                Effect: "Allow"
                Action:
                  - s3:GetObject
                Resource:
                  - !Sub "arn:aws:s3:::my-test/*"
  
  EC2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - Ref: EC2IAMRole
      InstanceProfileName: !Sub ${Prefix}-ec2-instance-profile


  EC2Instance1A:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro
      SubnetId: !ImportValue 
        Fn::Sub: "${VPCStack}-public-subnet1-id"
      SecurityGroupIds:
        - !Ref EC2SG
      IamInstanceProfile: !Ref EC2InstanceProfile
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          aws s3 cp s3://${UserDataBucket}/${UserDataShell} /tmp/${UserDataShell} # Parametersセクションで定義したバケットとシェルを/tmpにコピー
          chmod +x /tmp/${UserDataShell}
          ./tmp/${UserDataShell}
      Tags:     
        - Key: Name
          Value: !Sub ${Prefix}-ec2 

  EC2Instance1C:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro
      SubnetId: !ImportValue
        Fn::Sub: "${VPCStack}-public-subnet2-id"
      SecurityGroupIds:
        - !Ref EC2SG
      IamInstanceProfile: !Ref EC2InstanceProfile
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          aws s3 cp s3://${UserDataBucket}/${UserDataShell} /tmp/${UserDataShell} # Parametersセクションで定義したバケットとシェルを/tmpにコピー
          chmod +x /tmp/${UserDataShell}
          ./tmp/${UserDataShell}
      Tags:     
        - Key: Name
          Value: !Sub ${Prefix}-ec2 

  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTP access
      VpcId: !ImportValue 
        Fn::Sub: "${VPCStack}-VPCID"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 10.0.0.0/16
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 3.112.23.0/29

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

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

```

## インストール確認
- /tmpにS3に配置したシェルがある
![20250309_000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812406/c3ceae16-89f6-4e46-836c-1eca0f0a47a6.jpeg)

- インストール確認
![20250309_000005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812406/ff113144-41f2-46ee-bdac-836c9071ec80.jpeg)

![20250309_000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812406/ff67cdda-1add-48d3-ab03-2966251dca83.jpeg)

- ドキュメントルート確認
![20250309_000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812406/7558348d-01d0-48b5-9ae3-5edfb3f78fbb.jpeg)