Skip to main content
In this lesson we’ll add an Amazon EC2 instance to make the project more practical. Using the Pulumi AWS package and Python, we define an EC2 instance and export its public IP so you can SSH into it after deployment. Below is a concise, working Pulumi program that creates an Amazon S3 bucket and an EC2 instance. Replace the AMI ID with one appropriate for your AWS region (see the note below).
# __main__.py
import pulumi
from pulumi_aws import s3, ec2

# Create an S3 bucket
bucket = s3.Bucket('my-bucket')

# Export the name/ID of the bucket
pulumi.export('bucket_name', bucket.id)

# Create an EC2 instance. Replace ami with an AMI ID valid in your region.
ec2_instance = ec2.Instance('web-server',
    ami="ami-053b0d53c279acc90",    # replace with a region-appropriate AMI
    instance_type="t3.nano",
    key_name="test1",
    tags={
        "Name": "web"
    }
)

# Export the public IP of the instance so Pulumi prints it after creation.
# Note: this value will only be set if the instance receives a public IP (e.g., launched in a subnet
# with auto-assign public IP enabled or by specifying associate_public_ip_address).
pulumi.export('public_ip', ec2_instance.public_ip)
AMI IDs are region-specific. Select an AMI appropriate for your region (for example, Ubuntu 22.04 LTS) from the EC2 console or query the AWS CLI. See the EC2 console’s Launch Instance workflow for the image’s AMI ID.
To find and copy an AMI ID from the AWS Console, open the EC2 Launch Instance workflow and choose the desired image (Ubuntu in this example). Paste the AMI ID into the ami field of the code above.
A screenshot of the AWS EC2 "Launch Instance" console showing the Amazon Machine Image selection (Ubuntu Server 22.04 LTS) on the left and a summary panel on the right with the instance type (t2.micro), storage details, and a "Launch instance" button.
EC2 instance arguments at a glance:
Resource FieldPurposeExample
amiThe AMI ID to use for the instance (string)."ami-053b0d53c279acc90"
instance_typeInstance size/flavor."t3.nano"
key_nameName of an existing EC2 key pair for SSH access."test1"
tagsKey/value tags for easier identification in the console.{"Name":"web"}
Run pulumi up to preview and apply the changes. The preview shows the planned resources:
$ pulumi up

Previewing update (dev)

    Type                          Name               Plan
pulumi:pulumi:Stack              pulumi-demo-dev
└─ aws:ec2:Instance              web-server          create

Outputs:
  + public_ip : output<string>

Resources:
  + 1 to create
    2 unchanged

Do you want to perform this update? [Use arrows to move, type to filter]
> yes
After you confirm, Pulumi will create the EC2 instance and print outputs, including the public IP once the instance receives one:
Updating (dev)

    Type                              Name               Status
pulumi:pulumi:Stack                 pulumi-demo-dev
+  aws:ec2:Instance                  web-server         created (13s)

Outputs:
    bucket_name: "my-bucket-5d138fe"
+   public_ip  : "34.205.89.1"

Resources:
  + 1 created
  2 unchanged

Duration: 15s
With the public IP printed, SSH into the instance using the PEM file for the key pair you specified. For an Ubuntu AMI, the default user is ubuntu:
ssh -i test1.pem ubuntu@34.205.89.1
By default, the security group attached to a new EC2 instance may not allow SSH from the internet. If you cannot connect, check the instance’s Security Group inbound rules and ensure SSH (port 22) is allowed from your IP (or an appropriate CIDR). Restrict access to your IP rather than opening SSH to 0.0.0.0/0 whenever possible.
Troubleshooting checklist:
  • Verify the AMI ID is valid in your AWS region.
  • Confirm your key pair name matches an existing key pair and you have the corresponding PEM file.
  • Inspect the instance’s public IP in Pulumi outputs or the EC2 console.
  • Check Security Group inbound rules to allow SSH from your IP.
  • Ensure the instance was launched in a subnet that provides/associates a public IP or explicitly set associate_public_ip_address if needed.
References and further reading:
A screenshot of the AWS EC2 console displaying an instance's Details and Security sections, including public IP, VPC/subnet, launch time, and security group inbound/outbound rules. The left sidebar shows EC2 navigation options like Instances, Images, and Elastic Block Store.

Watch Video