simonw16
simonw16

Reputation: 1000

AWS CloudFormation, Stack update isn't modifying my EC2 configuration

I am trying to make sure my CloudFormation creates a stack that can be modified using Update or ChangeSets. I realise I have to use cfn-hup and init scripts to achieve this, and what I have seems to work with updating the SecurityGroups in my CloudFormation file, but it doesn't change the actual webserver infrastructure at all. I thought i'd be able to add/remove packages or update configuration files and those changes would be reflected.

Is this not possible? (Im using Amazon Linux 2)

Here is my file. I feel like this should be updating the nginx config file if it ever changes?

From what I can tell reading the AWS docs using services.sysvinit.nginx.files should then keep track of my nginx config that is listed, and reload nginx after the migration if a change is detected. It should also be updating the nginx file with any new change to the server {} block that I have.

AWSTemplateFormatVersion: "2010-09-09"

Parameters:

  VPC:
    Description: "ID of VPC"
    Type: String

  AMI:
    Description: "ID of base image"
    Type: String

  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."

  InstanceType:
    Description: "Amazon Instance Type"
    Default: t2.micro
    Type: String

  SSHLocation:
    Description: "IP address range that can be used to SSH to EC2 Instance"
    Type: String
    MinLength: 9
    MaxLength: 18
    Default: 0.0.0.0/0

Resources:

  ApiEc2Instance:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          InstallAndRun:
            - Configure
            - Install

        # install packages and setup files
        Install:
          packages:
            yum:
              php: []
              php-fpm: []
              php-mbstring: []
              php-bcmath: []
              php-pdo: []
              nginx: []

          files:
            /etc/nginx/conf.d/default.conf:
              content: !Sub |
                server {
                  listen 80;

                  root /var/www/html;

                  index index.php index.html index.htm;

                  gzip on;
                  gzip_vary off;
                  gzip_proxied static;
                  gzip_comp_level 6;
                  gzip_buffers 16 8k;
                  gzip_http_version 1.1;
                  gzip_types text/plain application/json;

                  charset utf-8;

                  location / {
                      try_files $uri $uri/ /index.php?$query_string;
                  }

                  location ~ \.php$ {
                      try_files $uri /index.php =404;
                      fastcgi_split_path_info ^(.+\.php)(/.+)$;
                      fastcgi_pass unix:/var/run/php-fpm/www.sock;
                      fastcgi_index index.php;
                      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                      include fastcgi_params;
                  }
                }

            /etc/php.d/default.ini:
              content: !Sub |
                display_errors = On

            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                verbose=1
                interval=5
              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.ApiEc2Instance.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource ApiEc2Instance --configsets InstallAndRun --region ${AWS::Region}
                runas=root
              mode: 000400
              owner: root
              group: root

          services:
            sysvinit:
              nginx:
                enabled: true
                ensureRunning: true
                files:
                  - /etc/nginx/conf.d/default.conf
              cfn-hup:
                enabled: true
                ensureRunning: true
                files:
                  - /etc/cfn/cfn-hup.conf
                  - /etc/cfn/hooks.d/cfn-auto-reloader.conf

        # configure any separate execution scripts
        Configure:
          commands:
            01_update_php:
              command: "amazon-linux-extras enable php7.4 nginx1 ansible2"
              test: "! grep -Fxq '[amzn2extra-php7.4]' /etc/yum.repos.d/amzn2-extras.repo"

    Properties:
      ImageId: !Ref "AMI"
      InstanceType: !Ref "InstanceType"
      SecurityGroupIds:
        - !Ref ApiSSHSecurityGroup
        - !Ref ApiWebSecurityGroup
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: "API Sandbox"
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum update -y aws-cfn-bootstrap

          # Install the files and packages from the metadata
          /opt/aws/bin/cfn-init -v \
            --stack ${AWS::StackName} \
            --resource ApiEc2Instance \
            --configsets InstallAndRun \
            --region ${AWS::Region}

          # Signal the status from cfn-init
          /opt/aws/bin/cfn-signal -e $? \
            --stack ${AWS::StackName} \
            --resource ApiEc2Instance \
            --region ${AWS::Region}

          #
          service nginx reload
    CreationPolicy:
      ResourceSignal:
        Timeout: PT5M

  ApiSSHSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: API SSH Admins
      GroupDescription: Enable public access via port 22
      VpcId: !Ref "VPC"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref "SSHLocation"

  ApiWebSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: API Public Web
      GroupDescription: Enable public web access via multiple ports
      VpcId: !Ref "VPC"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0

Upvotes: 1

Views: 1074

Answers (1)

Marcin
Marcin

Reputation: 238051

Based on the chat discussion.

hup takes 15 minutes by default to refresh. Thus the issue was cause by not-waiting this time as it seemed that hup was failing or doing nothing for the 15 minutes.

The time can be adjusted using interval variable as shown in the docs.

Upvotes: 1

Related Questions