I've been smacking my head on this for a couple days and finally got it. I know it's been a while but hopefully this helps someone else. Had a hard time finding answers elsewhere. Very similar to you, I had the ec2 instance set up, the security groups and vpc set up (those steps aren't too difficult and are well-documented). I had some successful pings, but was getting a "connection refused" error through the browser.
The "app.run_server()" parameters were the missing piece for me:
if __name__ == '__main__':
app.run_server(host= '0.0.0.0',port=80)
At that point calling the .py app gave me a 'permission denied,' which I was able to get around by running as sudo ("sudo python3 my_app.py") -- and by sudo pip install-ing necessary packages. (All through ssh, fwiw).
After finally running successfully I was given an IP from the dash app corresponding to my private IPv4 on EC2, and at that point could set my browser to the PUBLIC IPv4 and get to the app. Huzzah.
Playing around with it a little, it looks like as long as you have:
host= '0.0.0.0'
you'll run it online. Without that, it runs only locally (you'll see IP as 127.0.0.1). Then it's a matter of making sure whatever port you're using (:80, :443, :8050) is open according to firewalls and security groups. Dash for me defaults to :8050, and that port might be fine as long as it's allowed through security groups.
QUICK UPDATE:
I tried leaving it on port :8050, and also opened :8050 to all ipv4 in my security group. That let me run everything successfully without using "sudo python3".
if __name__ == '__main__':
app.run_server(host= '0.0.0.0',port=80)
With "python3 my_app.py" in ssh