无法在EC2上通过AWS CDK执行命令

1 投票
1 回答
49 浏览
提问于 2025-04-14 17:29

我现在的目标是利用CDK来创建一个EC2实例,以实现自动化。到目前为止,我已经成功地用CDK创建了一个EC2实例,并且配置了VPC、安全组和密钥。

不过,在通过CDK部署这个实例后,我遇到了一些问题,尝试在实例上执行命令时,命令没有正常执行。具体来说,就是这些命令在EC2实例上没有按预期运行。

为了参考,我在下面附上了代码:

from aws_cdk import (
    Stack,
    aws_ec2 as ec2,
    CfnOutput,
    CfnTag,
    aws_iam as iam,
    aws_route53 as route53,
    aws_route53_targets as targets
)
from constructs import Construct

 
class CdkTrsting1Stack(Stack):
 
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
 
        # VPC
        vpc = ec2.Vpc.from_vpc_attributes(
            self, "VPC",
            vpc_id="vpc-",
            availability_zones=['us-east-1a'],
            public_subnet_ids=['subnet-'] # Specify the actual subnet IDs here
        )
 
        # Security Group with inbound rule from everywhere
        security_group = ec2.SecurityGroup(
            self, "SecurityGroup",
            vpc=vpc,
            allow_all_outbound=True,
            security_group_name="AllowAllInbound",
        )
       
        security_group.add_ingress_rule(
            ec2.Peer.any_ipv4(),
            ec2.Port.tcp(22),  
        )
        security_group.add_ingress_rule(
            ec2.Peer.any_ipv4(),
            ec2.Port.tcp(80),  
        )
        security_group.add_ingress_rule(
            ec2.Peer.any_ipv4(),
            ec2.Port.tcp(443)  # SSH port
        )
 
        # IAM Role
        role = iam.Role(
            self, "EC2FullAccessRole",
            assumed_by=iam.ServicePrincipal("ec2.amazonaws.com"),
        )
 
        # Attach policy with full EC2 access to the role
        policy = iam.PolicyStatement(
            actions=["ec2:*"],
            resources=["*"]
        )
        role.add_to_policy(policy)
       
       
        # Create EC2 instance
        instance = ec2.Instance(
            self,
            "MyInstance",
            instance_type=ec2.InstanceType("t2.micro"),
            machine_image=ec2.MachineImage.generic_linux({
                "us-east-1": "ami-07d9b9ddc6cd8dd30"
            }),
            vpc=vpc,
            security_group=security_group,
            associate_public_ip_address=True,
            key_name="<key>",
            role=role,
            user_data=ec2.UserData.custom(
                "sudo mkdir Trial101"
            )
        )
       
        user_data = ec2.UserData.for_linux()
        user_data.add_commands(
            "#!/bin/bash",
            "sudo apt update && sudo apt upgrade -y",  
            "sudo apt install git",  
            "git clone  <git_url>",
            "cd <folder_path>",
            "sh startup_run.sh"
        )
 
     
       
        publicIp = instance.instance_public_ip;
 
        # Output Instance ID
        CfnOutput(self, "InstanceId", value=instance.instance_id)
        CfnOutput(self, "InstanceIp", value=instance.instance_public_dns_name)
user_data = ec2.UserData.for_linux()
user_data.add_commands(
            "#!/bin/bash",
            "sudo apt update && sudo apt upgrade -y",  # Update all packages
            "sudo apt install git",  # Install Git
            "git clone <git_link>",
            "cd /<folder_path>",
            "sh startup_run.sh"
)

#将用户数据附加到实例上 instance.user_data.add_commands(str(user_data))

1 个回答

2

解释

你没有提到是否在日志中看到任何错误,但多加一个shebang其实是没必要的。

for_linux已经自动使用#!/bin/bash作为shebang。你可以查看CDK的源代码。如果需要,shebang也可以自定义(具体可以参考文档),但在这里其实也不太需要。

不过,shebang并不一定是最大的问题。以sudo身份运行可能才是。

根据文档

作为用户数据输入的脚本是以root用户身份运行的,所以在脚本中不要使用sudo命令。

所以你也需要去掉sudo的指令,因为这也是多余的。

第三个问题是运行apt install时没有自动接受,应该加上-y

解决方案

这样应该可以正常工作:

user_data = ec2.UserData.for_linux()
user_data.add_commands(
            "apt update && apt upgrade -y",  # Update all packages
            "apt -y install git",  # Install Git
            "git clone <git_link>",
            "cd /<folder_path>",
            "sh startup_run.sh"
)

撰写回答