带有letencrypt SSL证书的AWS Cloudformation模板

时间:2019-09-12 10:36:17

标签: amazon-cloudformation

我想使用

创建一个AWS Cloudformation模板
  • 具有一个Apache网络服务器和一个letencrypt SSL证书的单个EC2实例
  • Route53 A记录,它是动态模板参数

我可以运行letencrypt,因为我需要完成挑战https://letsencrypt.org/de/docs/challenge-types/

问题: HTTP-01挑战需要在EC2实例之前创建Route53 A记录,但这是不可能的,因为我需要EC2实例的IP地址才能创建Route53。一条记录。

我曾考虑过使用EIP,但是EIP仅在创建EC2实例后才能关联,因此挑战也失败了。

dns-01挑战在cloudformation中是不可能的。

2 个答案:

答案 0 :(得分:0)

要实现此目的,很不明智的方法是在cloudfromation中使用aws cli,但这不是很优雅,因为这将要求EC2实例有权更改route53记录。

ip可以这样观察

curl http://169.254.169.254/latest/meta-data/public-ipv4

,模板将如下所示:

  WebServerInstance:
    Type: 'AWS::EC2::Instance'
    Metadata:
      AWS::CloudFormation::Init:
......
        InstallSSLCertificate:
          commands:
            createRoute53Cli:
              command: 'sudo aws route53 change-resource-record-sets --params here'
            installCertbotSslCertificate:
              command: !Sub
                - 'sudo certbot -i apache -a apache --preferred-challenges http -d ${Domain} -m ${AdminEmail} -n --redirect --agree-tos'
                - { Domain: !Ref Domain, AdminEmail: !Ref AdminEmail }
          packages:
            yum:
              certbot: []
              python2-certbot-apache: []

答案 1 :(得分:0)

这将在具有apache网络服务器的Amazon Linux 2 EC2实例上安装certbot SSL证书

问题是,对于ssl验证挑战,您需要一个指向该EC2实例的域,但是可以在使用cloudformation创建EC2实例之后对域进行设置。

我找到了一种解决方案,可以等到使用CloudFormation设置域

    Resources:
      WebServerInstance:
        Type: AWS::EC2::Instance
        Metadata:
          AWS::CloudFormation::Init:


            InstallApache:
              packages:
                yum:
                  httpd: []

           InstallCerbotSsl:
              packages:
                yum:
                  certbot: []
                  python2-certbot-apache: []
              files:
                /use/bin/install_certbot_after_domain_is_set_route53.sh:
                  content: !Sub |
                      #!/bin/bash

                      while true; do
                        certbot -i apache -a apache --preferred-challenges http -d "${Domain}" -m ${AdminEmail} -n --redirect --agree-tos

                        if [ $? -eq 0 ]
                        then
                          echo "Certbot success"

                          service httpd restart
                          break
                        else
                          echo "retry..."
                          sleep 10
                        fi
                      done
                  mode: '000600'
                  owner: root
                  group: root
            InstallCrontab:
              files:
                /var/spool/cron/root:
                  content: !Sub |
                    # m h dom mon dow      command
                    39 1,13 * * * certbot renew --no-self-upgrade > /dev/null 2>&1

                  mode: '000600'
                  owner: root
                  group: root

这将是堆栈的域,certbot需要使用该域来验证httpd挑战:

DNSRecord:
  Type: AWS::Route53::RecordSet
  Properties:
    HostedZoneName: foo.de.
    Name: !Ref Domain
    Type: A
    TTL: 300
    ResourceRecords:
      - !GetAtt WebServerInstance.PublicIp

和一个UserData触发器,该触发器将在CF堆栈创建成功信号fpr之后执行,以在创建过程中继续使用

 UserData:
    # is executed as root user
    Fn::Base64: !Sub |
        #!/bin/bash

        # create EC2 instance
        yum update -y aws-cfn-bootstrap

        # create EC2 instance
        /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --configsets InstallAndRun --region ${AWS::Region}

        # send create success signal to cloudformation
        /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region}

        # update all packages to latest
        yum update -y

        service httpd restart

        # install certbot sll certificate, can take some time until domain is set
        bash /use/bin/install_certbot_after_domain_is_set_route53.sh > /use/bin/install_certbot.log

        # reboot system
        reboot