powershell 如何在EC2示例上发现AWS Cloudformation堆栈名以与cfn-init命令一起使用

pftdvrlh  于 2023-05-07  发布在  Shell
关注(0)|答案(2)|浏览(107)

我们使用Cloudformation部署了一些Windows EC2示例,这些示例使用cfn-init脚本进行配置。
为了稍后更新示例上的组件,我们需要使用cfn-init助手脚本重新运行一些Cloudformation::Init配置集,其中一个必需的参数 --stack 是堆栈名称。我希望这个值可以通过EC2 Instance Metadata作为一个单独的调用动态地获得,但是我没有找到它。
我发布了一个解决方案脚本,但我仍然想知道是否有一个更简单,强大的方式,我错过了。

dddzy1tm

dddzy1tm1#

您可能希望在cloudformation模板中定义cfn-hup,以便它放置包含所需变量的文件:

  • 来自文档 *
...
  LaunchConfig:
    Type: "AWS::AutoScaling::LaunchConfiguration"
    Metadata:
      QBVersion: !Ref paramQBVersion
      AWS::CloudFormation::Init:
...
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --configsets wordpress_install --region ${AWS::Region}
                runas=root
              mode: "000400"
              owner: "root"
              group: "root"
...

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-hup.html

kiz8lqtg

kiz8lqtg2#

由于用户数据脚本中包含的初始cfn-init命令包含${AWS::StackName} Psuedo参数,因此我们可以解析此脚本以提取它。下面的PowerShell脚本说明了该技术,类似的bash脚本可以在Linux示例上使用:

function Get-CfnInitStackName {
    [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
    $userDataScript = (Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/user-data).script
    # Exact regex would be determined by your command usage in the UserData element of your Cloudformation template
    if ($userDataScript -match 'cfn-init.+ --stack (?<stackName>\S+) --resource') {
        $stackName = $Matches.stackName
    } else {
        throw "Stack name not found within user data script" + [System.Environment]::NewLine + $userDataScript
    }

    $stackName
}

function Invoke-CfnInitConfigset([string]$ConfigSet = 'deploy_full') {
    $stackName = Get-CfnInitStackName
    cfn-init --verbose --stack $stackName --resource Instance --region ap-southeast-2 --configsets $ConfigSet
    # TODO: Handle result code and disploy cfn-init.log output
}

注意,我考虑使用aws cloudformation describe-stack-resources调用提供来自元数据的ec2 instance-id作为--physical-resource-id参数。这确实有效,但这是对外部服务调用的额外依赖,并且需要扩展IAM示例配置文件权限。

相关问题