[英]Cloudformation stack default parameter SSM Parameter store
I am trying to launch a jupyterlab instance using cloudformation (its something I do a lot and sagemaker does not have a 1y free tier) so the beginning looks like this which does not work.我正在尝试使用 cloudformation 启动一个 jupyterlab 实例(这是我经常做的事情,sagemaker 没有 1y 免费层)所以一开始看起来像这样不起作用。 Specifically the password parameter
特别是密码参数
# AWSTemplateFormatVersion: "2010-09-09"
Description: Creates a Jupyter Lab Instance with an Elastic Load Balancer
Parameters:
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.
Default: eduinstance
VPC:
Description: VPC ID of the VPC in which to deploy this stack.
Type: AWS::EC2::VPC::Id
ConstraintDescription: Must be the name of a valid VPC
Default: vpc-10a7ac6a
Subnets:
Type: List<AWS::EC2::Subnet::Id>
Default: subnet-8cde25d3,subnet-531fda72,subnet-4bbe3006
Description: >-
Subnets for the Elastic Load Balancer.
Please include at least two subnets
Password:
Type: String
NoEcho: false
MinLength: 4
Default: '{{resolve:ssm:JLabPassword:1}}'
Description: Password to set for Jupyter Lab
EBSVolumeSize:
Type: Number
Description: EBS Volume Size (in GiB) for the instance
Default: 8
MinValue: 8
MaxValue: 64000
ConstraintDescription: Please enter a value between 8 GB and 64 TB
EC2InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- c5.large
- m5.large
Description: Enter t2.micro, c5.large or m5.large. Default is t2.micro.
Conditions:
JupyterPasswordDefault: !Equals
- !Ref Password
- DEFAULT
Resources:
ALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Scheme: internet-facing
SecurityGroups:
- !GetAtt [ALBSG, GroupId]
Subnets: !Ref Subnets
Type: application
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ALBTargetGroup
LoadBalancerArn: !Ref ALB
Port: 80
Protocol: HTTP
ALBTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Port: 8888
Protocol: HTTP
Targets:
- Id: !Ref ComputeInstance
TargetType: instance
VpcId: !Ref VPC
ComputeInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref ComputeIAMRole
ComputeInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
SubnetId: !Select [0, !Ref Subnets]
KeyName: !Ref KeyName
ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2:33}}'
SecurityGroupIds:
- !GetAtt [ComputeSG, GroupId]
IamInstanceProfile: !Ref ComputeInstanceProfile
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeType: gp2
VolumeSize: !Ref EBSVolumeSize
DeleteOnTermination: true
UserData:
Fn::Base64: !Sub
- |
#!/bin/bash
yum update -y
yum install python3-pip -y
yum install java-1.8.0-openjdk -y
cd /home/ec2-user/
wget https://repo.anaconda.com/archive/Anaconda3-2020.11-Linux-x86_64.sh
sudo -u ec2-user bash Anaconda3-2020.11-Linux-x86_64.sh -b -p /home/ec2-user/anaconda
echo "PATH=/home/ec2-user/anaconda/bin:$PATH" >> /etc/environment
source /etc/environment
jupyter notebook --generate-config
mkdir .jupyter
cp /root/.jupyter/jupyter_notebook_config.py /home/ec2-user/.jupyter/
echo "c = get_config()" >> .jupyter/jupyter_notebook_config.py
echo "c.NotebookApp.ip = '*'" >> .jupyter/jupyter_notebook_config.py
NB_PASSWORD=$(python3 -c "from notebook.auth import passwd; print(passwd('${password}'))")
echo "c.NotebookApp.password = u'$NB_PASSWORD'" >> .jupyter/jupyter_notebook_config.py
rm Anaconda3-2020.11-Linux-x86_64.sh
mkdir Notebooks
chmod 777 -R Notebooks .jupyter
su -c "jupyter lab" -s /bin/sh ec2-user
- password: !Ref Password #!If [JupyterPasswordDefault, '{{resolve:ssm:JupyterLabPassword:1}}', !Ref Password]
ALBSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for JupyterLab ALB. Created Automatically.
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
Description: Allows HTTP Traffic from anywhere
FromPort: 80
ToPort: 80
IpProtocol: tcp
ComputeSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for JupyterLab EC2 Instance. Created Automatically.
SecurityGroupIngress:
- Description: Allows JupyterLab Server Traffic from ALB.
FromPort: 8888
IpProtocol: tcp
SourceSecurityGroupId: !GetAtt [ALBSG, GroupId]
ToPort: 8890
- CidrIp: 0.0.0.0/0
Description: Allows SSH Access from Anywhere
FromPort: 22
ToPort: 22
IpProtocol: tcp
ComputeIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
Description: Allows EC2 Access to S3. Created Automatically.
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonS3FullAccess
- arn:aws:iam::aws:policy/AmazonSageMakerFullAccess
Outputs:
URL:
Description: URL of the ALB
Value: !Join
- ''
- - 'http://'
- !GetAtt
- ALB
- DNSName
ConnectionString:
Description: Connection String For SSH On EC2
Value: !Join
- ''
- - 'ssh -i "'
- !Ref KeyName
- '.pem" ec2-user@'
- !GetAtt
- ComputeInstance
- PublicDnsName
It however interprets the string literally so I don't actually get my password but the resolve... itself.然而,它从字面上解释字符串,所以我实际上并没有得到我的密码,而是解析......本身。
Based on the comments and new, updated template by OP, and to expand on @DennisTraub answer.基于 OP 的评论和新的更新模板,并扩展 @DennisTraub 答案。
SSM parameters resolve in almost all cases in the template, with the exception of UserData
(btw, Init
will also not work). SSM 参数在模板中的几乎所有情况下都解析,除了
UserData
(顺便说一句, Init
也不起作用)。 This means, that dynamic reference will not resolve when used in the context of UserData
.这意味着,在
UserData
的上下文中使用时,动态引用将无法解析。 This is due to security issues.这是由于安全问题。
UserData
can be read in plain text by anyone who can view basic attributes of the instance.任何可以查看实例基本属性的人都可以以纯文本形式读取
UserData
。 This means, that your JLabPassword
would be in plain text available in UserData
for everyone to see, if such resolution would be possible.这意味着,您的
JLabPassword
将以纯文本形式出现在UserData
中,供所有人查看,如果这样的解决方案可行的话。
To rectify the issue, the SSM parameters should be used in UserData
as follows:为解决此问题,应在
UserData
中使用 SSM 参数,如下所示:
Attach IAM permission ssm:GetParameter
to the instance role/profile which allows instance to access the SSM Parameter Store.将 IAM 权限
ssm:GetParameter
附加到允许实例访问 SSM 参数存储的实例角色/配置文件。
Instead on {{resolve:ssm:JLabPassword:1}}
in your Parameter, you can just pass JLabPassword
so that the name of the SSM paramtter gets passed into the UserData
, not the actual value of it.而不是在参数中的
{{resolve:ssm:JLabPassword:1}}
上,您可以只传递JLabPassword
以便将 SSM 参数的名称传递给UserData
,而不是它的实际值。
In the UserData
, please use AWS CLI get-parameter to get the actual value of your JLabPassword
.在
UserData
中,请使用 AWS CLI get-parameter获取JLabPassword
的实际值。
The above ensures that the value of JLabPassword
is kept private and not visible in plain text in UserData
.以上确保
JLabPassword
的值是私有的,并且在UserData
的纯文本中不可见。
Your passwort parameter's default value is missing the service name ( ssm
) as well as single quotes.您的密码参数的默认值缺少服务名称 (
ssm
) 以及单引号。
// What you have:
Password:
Default: {{resolve:JupyterPassword:1}}
...
// What it should be:
Password:
Default: '{{resolve:ssm:JupyterPassword:1}}'
...
Update: You've fixed the code in your question.更新:您已经修复了问题中的代码。 Did my answer and the comments below solve your question?
我的回答和下面的评论解决了你的问题吗? If not, I'm not sure what else you need.
如果没有,我不确定您还需要什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.