簡體   English   中英

如何使用 AWS CDK 獲取偽參數用戶數據?

[英]How to obtain pseudo-parameters user data with AWS CDK?

我想將此工作 CloudFormation 代碼轉換為合適的 Python AWS CDK 版本。 EC2 應在 VPC 內啟動。 用戶數據用於安裝應用程序。 完成后,我需要回調 Cloudformation。

UserData:
        Fn::Base64: !Sub |
          <script>
          cfn-signal.exe --exit-code 0 --stack ${AWS::StackId} --resource EC2Instance --region ${AWS::Region}
          </script>

我嘗試對aws_cdk.core.Fn.base64使用直接方式,該方式aws_cdk.core.Fn.base64用於 EC2 用戶數據中的偽參數聲明。

這是我目前的狀態:

EC2InstanceUserData = aws_ec2.UserData.for_windows()
EC2InstanceUserData.add_commands(
   "cfn-signal.exe --exit-code 0 ",
   "--stack ",
   VpcStack.stack_id(XXX, e.g. self?), # not working
   " --resource ",
   VpcStack.get_logical_id(XXX, e.g. self?), # not working
   " --region ",
   VpcStack.region(XXX, e.g. self?) # not working
)

方法一:

優點:

  • 可以接受任意數量的變量,例如上下文中定義的變量,而不僅僅是core.Aws對象中的變量,例如區域或賬戶 ID。

缺點:

  • 您將需要使用$!{而不僅僅是${user_data.sh腳本中的所有常規變量的引用添加前綴。

腳步

使用映射字典並將其解析為Fn.sub函數。 我個人喜歡在我的user_data.sh腳本頂部聲明的這些,而不是整個替換,因此使用雙下划線作為前綴和后綴。 請注意,您仍然需要將映射視為變量而不是字符串。

IE

$cat user_data.sh
ACCOUNT_ID="${__ACCOUNT_ID__}"
REGION="${__REGION__}"

## Updates
yum update -y

## Fix time
ln -sf /usr/share/zoneinfo/Australia/Melbourne /etc/localtime

## ECR Repo
ECR_REPO="${!ACCOUNT_ID}.dkr.ecr.${!REGION}.amazonaws.com/"
...

在我的堆棧聲明中,我然后放置以下字典:

mappings = {"__ACCOUNT_ID__": self.account,
            "__REGION__": self.region}

並將user_data.sh讀入子函數,映射dict作為第二個參數

with open("user_data/user_data.sh", 'r') as user_data_h:
    # Use a substitution
    user_data_sub = core.Fn.sub(user_data_h.read(), mappings)

然后使用 UserData 模塊中的自定義屬性

# Import substitution object into user_data set
user_data = ec2.UserData.custom(user_data_sub)

方法二

優點:

  • 無需更改 bash 語法

缺點:

  • 令牌變量難以閱讀,並且僅限於core.Aws對象的屬性。 例如 AccountID 和 Region。

腳步

您可以在 cdk 工作流中運行打印語句,以幫助您確定諸如core.Aws.ACCOUNT_IDcore.Aws.REGION類的變量的評估結果,並在 user_data 腳本中使用這些變量。 (我正在用 python 編寫我的部署,並將它從 ec2 基於來自aws 官方示例 repo的現有 VPC。

IE:

host = ec2.Instance(...)
print(core.aws.ACCOUNT_ID)
print(core.Aws.REGION)

然后我運行cdk synth產生:

${Token[AWS::AccountId.0]}
${Token[AWS::Region.4]}
Resources:...

從這里我可以在我的 user_data 腳本中使用這些:即

#!/bin/bash
ACCOUNT_ID="${Token[AWS::AccountId.0]}"
REGION="${Token[AWS::Region.4]}"

## Updates
yum update -y

## Fix time
ln -sf /usr/share/zoneinfo/Australia/Melbourne /etc/localtime

現在請注意,當重新運行cdk synth ,yaml 構造函數會將它們識別為特殊的(yaml 雙間距是已知的 cdk 錯誤):

...
UserData:
        Fn::Base64:
          Fn::Join:
            - ""
            - - >-
                #!/bin/bash


                # AWS vars:

                ACCOUNT_ID="
              - Ref: AWS::AccountId
              - >-
                "

                REGION="
              - Ref: AWS::Region
              - >-
                "

                ## Updates
                yum update -y

                ## Fix time
                ln -sf /usr/share/zoneinfo/Australia/Melbourne /etc/localtime

                ## ECR Repo
                EC2_REPO="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/"
...

我發現以下內容可以與 python 一起使用

from aws_cdk import (
  aws_ec2,
  core
)

host = aws_ec2.Instance(...)

host.add_user_data('', join([
  'yum install -y aws-cfn-bootstrap\n',
  f'/opt/aws/bin/cfn-init -v -s {core.Aws.STACK_NAME} -r {host.node.default_child.logical_id}\n'
])

meta_data = {
  'config': {
    'packages': {...},
    'files': {...},
     ...
    }
}

# for adding the meta data in a way that gets synth
host.node.default_child.add_overide('Metadata.AWS::CloudFormation::Init', meta_data)

這是使用您從host.node.default_child獲得的CfnInstance對象

您可以使用核心模塊訪問這些偽參數:

from aws_cdk import core

# other code...

EC2InstanceUserData = aws_ec2.UserData.for_windows()
EC2InstanceUserData.add_commands(
   "cfn-signal.exe --exit-code 0 ",
   f"--stack {core.Aws.STACK_ID}",
   f" --resource {EC2Instance}",  # Without more context, I'm not sure if this is exactly what you're wanting
   f" --region {core.Aws.REGION}",
)

# other code ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM