CloudFormation テンプレートから初期化するときにルート ボリュームにタグを付ける方法はありますか?
-
21-12-2019 - |
質問
クラウド形成スクリプトを使用してインスタンスを作成しています。
OS パーティションをアタッチする唯一の方法は、「BlockDeviceMappings」プロパティを使用することでした。(以前に「ボリューム」プロパティを使用しようとしましたが、インスタンスをマウントできませんでした。システムは、/dev/sda がすでにマップされており、インスタンスの作成をロールバックしたと通知しました)
私のテンプレートの関連部分は次のとおりです。
"Resources" :
{
"Ec2Instance" :
{
"Type" : "AWS::EC2::Instance",
"Properties" :
{
"BlockDeviceMappings" :
[{
"DeviceName" : "/dev/sda",
"Ebs" :
{
"VolumeSize" : { "Ref" : "RootVolumeSize" },
"SnapshotId" :
{ "Fn::FindInMap" : [ "RegionMap",
{ "Ref" : "AWS::Region" }, "RootVolumeSnapshotId" ]
}
}
}],
...
}
}
私の質問は、ここで作成している Ebs ボリュームに「BlockDeviceMappings」プロパティをどのようにタグ付けできるかということです。明確な解決策は見つかりませんでした。
ありがとう。
解決
は、AWS CLIインタフェース、IAMロール、およびUSERDATAの初期化を介して動作させることができました。
これをAWS::EC2::Instance:Properties:UserData
{ "Fn::Base64" : { "Fn::Join" : [ "\n", [
"#!/bin/bash",
"set -eux",
"exec > >(tee /tmp/user-data.log | logger -t user-data -s 2>/dev/console) 2>&1",
{ "Fn::Join" : [ "", [
"AWS_STACK_NAME='", { "Ref" : "AWS::StackName" }, "'"
]]},
{ "Fn::Join" : [ "", [
"AWS_ROOT_VOLUME_SNAPSHOT_ID='",
{ "Fn::FindInMap" :
[ "RegionMap", { "Ref" : "AWS::Region" }, "RootVolumeSnapshotId" ]},
"'"
]]},
"AWS_INSTANCE_ID=$( curl http://169.254.169.254/latest/meta-data/instance-id )",
"",
"AWS_HOME=/opt/aws",
"AWS_BIN_DIR=\"${AWS_HOME}/bin\"",
"export EC2_HOME=\"${AWS_HOME}/apitools/ec2\"",
"export JAVA_HOME=/etc/alternatives/jre_1.7.0",
"",
"ROOT_DISK_ID=$(",
" \"${AWS_BIN_DIR}/ec2-describe-volumes\" \\",
" --filter \"attachment.instance-id=${AWS_INSTANCE_ID}\" \\",
" --show-empty-fields \\",
" | grep '^VOLUME' \\",
" | awk '{printf \"%s,%s\\n\", $4, $2}' \\",
" | grep '^${AWS_ROOT_VOLUME_SNAPSHOT_ID}' \\",
" | cut --delimiter=, --fields=2",
" exit ${PIPESTATUS[0]}",
" )",
"\"${AWS_BIN_DIR}/ec2-create-tags \\",
" \"${ROOT_DISK_ID}\" \\",
" --tag \"Name=${AWS_STACK_NAME}-root\"",
""
]]}}
.
ボリュームとタグの作成を記述できるIAMロールへの参照を追加する必要があります。
これを「リソース」に追加しました:
"InstanceProfile" :
{
"Type" : "AWS::IAM::InstanceProfile",
"Properties" :
{
"Path" : "/",
"Roles" : [ "ec2-tag-instance" ]
}
}
.
Instance
リソースでこのプロファイルを参照しました:
"Ec2Instance" :
{
"Type" : "AWS::EC2::Instance",
"Properties" :
{
...
"IamInstanceProfile" : {"Ref" : "InstanceProfile"},
...
}
}
.
およびIAM
UIでは、ec2-tag-instance
という新しい役割を作成し、このポリシーを割り当てます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:CreateTags"
],
"Resource": "*"
}
]
}
.
これは、BlockDeviceMappings:Ebs
がTags
要素をサポートしていた場合、多くのことになるでしょう。
他のヒント
感謝Alex、
ec2-create-tags :)
の後に二重引用符がありませんでした "\"${AWS_BIN_DIR}/ec2-create-tags\" \\",
" \"${ROOT_DISK_ID}\" \\",
" --tag \"Name=${AWS_STACK_NAME}-root\"",
.
その上、インスタンスがデフォルトのUS-East-1リージョンに存在していない場合は、 ec2-create-tags - 領域領域"を指定してください。>と記述ボリュームコマンド
CloudFormation スタックがタグ付けされており、EC2 に接続されたボリュームにスタックからタグをコピーする場合は、以下の UserData 値を使用できます。
Fn::Base64: !Sub |
#!/bin/bash -xe
exec > /tmp/part-001.log 2>&1
# --==Tagging Attached Volumes==--
TAGS=$(aws cloudformation describe-stacks --stack-name ${AWS::StackName} --query 'Stacks[0].Tags' --region ${AWS::Region})
EC2_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
EBS_IDS=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values="$EC2_INSTANCE_ID" --region ${AWS::Region} --query 'Volumes[*].[VolumeId]' --out text | tr "\n" " ")
aws ec2 create-tags --resources $EBS_IDS --tags "$TAGS" --region ${AWS::Region}
TAGS=$(echo $TAGS | tr "Key" "key" | tr "Value" "value")
aws ecs tag-resource --resource-arn arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${EcsClusterName} --tags "$TAGS"
デバッグ用にすべての stdout と stderr をファイルに書き込みます。
`exec > /tmp/part-001.log 2>&1
(許可が必要です) スタックからタグを取得します。
TAGS=$(aws cloudformation describe-stacks --stack-name ${AWS::StackName} --query 'Stacks[0].Tags' --region ${AWS::Region})
メタデータ エンドポイントから EC2 インスタンス ID を取得します。
EC2_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
(許可が必要です) EBS IDS を取得します。
EBS_IDS=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values="$EC2_INSTANCE_ID" --region ${AWS::Region} --query 'Volumes[*].[VolumeId]' --out text | tr "\n" " ")
(許可が必要です) EBS ボリュームにタグを追加します。
aws ec2 create-tags --resources $EBS_IDS --tags "$TAGS" --region ${AWS::Region}
ECS タグ付け用のタグのフォーマット:
TAGS=$(echo $TAGS | tr "Key" "key" | tr "Value" "value")
(許可が必要です) ECS クラスターにタグを付けます。
aws ecs tag-resource --resource-arn arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${EcsClusterName} --tags "$TAGS"
ポリシーは次のようになります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DeleteTags",
"ec2:CreateTags",
"ecs:TagResource",
"cloudformation:DescribeStacks"
],
"Resource": "*"
}
]
}
CloudWatch Templateを使用して、CloudWatchイベントルールとLambdaのようなリソースを作成できます。Lambda呼び出しは、インスタンス作成イベントがある場合だけでなく、インスタンスタグに更新が発生した場合に発生する可能性があります。
これは私が私のEC2 userdataにしたことです。私はそれが上記の答えよりもはるかに単純だと思います。
Key=<Your Tag Name>
Value=<Your Tag Value>
Region=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep -oP "(?<=\"region\" : \")[^\"]+")
aws ec2 create-tags --resources $(aws ec2 describe-instances --instance-ids $(curl -s http://169.254.169.254/latest/meta-data/instance-id) --region $Region | grep -oP "(?<=\"VolumeId\": \")[^\"]+") --tags Key=$Key,Value=$Value --region $Region
.