Why does running cloud-init script on EC2 change my shell? - amazon-ec2

Calling all cloud-init and EC2 gurus...
I can't figure this out. I'm using a cloud-init script to bootstrap an EC2 aws-ami instance (through AWS CloudFormation) and when I include the write_files property it changes the command prompt on the instance to -bash-4.2$. If I don't include write_files, I get the regular EC2 shell.
Here is my script so far:
#cloud-config
repo_update: true
repo_upgrade: all
packages:
- gcc
- git
- ruby24
- ruby24-devel
runcmd:
- update-alternatives --set ruby /usr/bin/ruby2.4
write_files:
- path: /home/ec2-user/some-file.yml
owner: root:root
permissions: '0644'
content: |
<<--SOME-CONTENT-->
final_message: 'The Build Server is ready!'
Anybody know why this is happening or what I might be doing wrong that's making cloud-init change the shell? Or maybe it's a bug/known-issue with cloud-init? This is driving me nuts.
I've already checked the logs /var/log/cloud-init.log and /var/log/cloud-init-output.log and there are no errors or anything to suggest anything went wrong.

I figured it out, something within cloud-init was not setting the variable $PS1, so the built-in default \s-\v\$ is used.
I fixed it by bootstrapping a modified ~/.bashrc file.
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
parse_git_branch() {
if ! git rev-parse --git-dir > /dev/null 2>&1; then
return 0
fi
git_branch=$(git branch 2>/dev/null| sed -n '/^\*/s/^\* //p')
echo "[$git_branch]"
}
PS1="${debian_chroot:+($debian_chroot)}\[\033[38;5;39m\]\u#\h\[\033[00m\]:\[\033[01;36m\]\w\[\033[00m\]\[\033[38;5;118m\]\$(parse_git_branch)\[\033[00m\]$ "

Related

cloud-init runcmd (using MAAS)

I'm unable to run bash scripts in "runcmd:" that aren't inline.
runcmd:
- [ bash, -c, echo "=========hello world=========" >>foo1.bar ]
- [ bash, -c, echo "=========hello world=========" >>foo2.bar ]
- [ bash, -c, /usr/local/bin/foo.sh ]
The first two lines are successfully run on the deployed Ubuntu instance. However, the foo.sh doesn't seem to run.
Here is /usr/local/bin/foo.sh:
#!/bin/bash
echo "=========hello world=========" >>foosh.bar
foo.sh has executable permissions for root and resides on the MAAS server.
I've looked at the following but they don't seem to sort out my issue:
Cannot make bash script work from cloud-init
run GO111MODULE=on go install . ./cmd/... in cloud init
https://gist.github.com/aw/40623531057636dd858a9bf0f67234e8
Any help or tips would be greatly appreciated.
Anything you run using runcmd must already exist on the filesystem. There is no provision for automatically fetching something from a remote host.
You have several options for getting files there. Two that come to mind immediately are:
You could embed the script in your cloud-init configuration using the write-files directive:
write_files:
- path: /usr/local/bin/foo.sh
permissions: '0755'
content: |
#!/bin/bash
echo "=========hello world=========" >>foosh.bar
runcmd:
- [bash, /usr/local/bin/foo.sh]
You could fetch the script from a remote location using curl (or similar tool):
runcmd:
- [curl, -o, /usr/local/bin/foo.sh, http://somewhere.example.com/foo.sh]
- [bash, /usr/local/bin/foo.sh]

Trying to set GOPATH and GOROOT in AWS EC2 user data, but it is not working

I am trying to set up GOPATH GOROOT in my AWS EC2 Ubuntu 20.04 user data, but it never worked, every time I connect to the AWS EC2 and view the log in /var/log/cloud-init-output.log it always says
go: not found, but if I key in the echo part it will work.
I am trying to set up multiple EC2 with this basis, so I can't key in every instance myself.
The CloudFormation yaml user data part is below:
UserData:
Fn::Base64: |
#!/bin/bash
wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz
tar -C /usr/local -zxvf go1.14.4.linux-amd64.tar.gz
mkdir -p ~/go/{bin,pkg,src}
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
echo 'export GOROOT=/usr/local/go' >> ~/.bashrc
echo 'export PATH=$PATH:$GOPATH/bin:$GOROOT/bin' >> ~/.bashrc
echo 'export GO111MODULE=auto' >> ~/.bashrc
source ~/.bashrc
apt -y update
apt -y install mongodb wget git
systemctl start mongodb
apt -y install git gcc cmake autoconf libtool pkg-config libmnl-dev libyaml-dev
go get -u github.com/sirupsen/logrus
cd ~
git clone --recursive https://github.com/williamlin0504/free5gcWithOCF.git
cd free5gcWithOCF
make
And here is the error inside /var/log/cloud-init-output.log
Error while user data runs
Is there anyone is familiar with this, please I need some help~
In your error message, in the Makefile at line 30 there is a program bin/amf being used
This program appears to be a shell script with a problem in line 1
The nature of the problem is "go: not found"
If you have the bare word "go" in line 1 of the shell script and the path cannot find it then this is what will happen
Probably you need to alter the last line of your userdata shell script to say
PATH=/usr/local/go/bin:$PATH make
I know you have a source command earlier in the script that is supposed to set this up but it doesn't do what you think it does

AWS EC2 User Data: Commands not recognized when using sudo

I'm trying to create an EC2 User-data script to run other scripts on boot up. However, the scripts that I run fail to recognize some commands and variables that I'd already declared. I'm running the commands as the "ubuntu" user but it still isn't working.
My user-data script looks something like this:
export user="ubuntu"
sudo su $user -c ". ./run_script"
Within the script, I have these lines:
THIS_PATH="/some/path"
echo "export SOME_PATH=$THIS_PATH" >> ~/.bashrc
source ~/.bashrc
However, the script can't run SOME_PATH/application, and echo $SOME_PATH this returns a blank line. I'm confused because $SOME_PATH/application works when I log into the EC2 using SSH and my debug logs using whoami returns "ubuntu."
Am I missing something here?
Your data script is executed as root and su command leaves $HOME and other ENV variables intact (note that sudo is redundant). "su -" does not help either
So, do not use ~ or $HOME but full path /home/ubuntu/.bashrc
I found out the problem. It seems that source ~/.bashrc isn't enough to restart the shell -- the environment variables worked after I referenced them in another bash script.

using the -d flag with the read command in Ubuntu via the vagrant provision command

As part of my provisioning tasks in Vagrant, I am using shyaml to parse a yaml file and create my virtual host files for my various projects. In my particular case, I am trying to set environment variables.
My yaml file looks like:
sites:
site1:
...
env:
DB_NAME: example
DB_USER: root
DB_PASSWORD: root
DB_HOST: localhost
TABLE_PREFIX: www_
According to the docs I should this code to grab both the keys and values of mappings:
#!/bin/sh
readLine() {
while [ "$1" ]; do
IFS=$'\0' read -r -d '' "$1" || return 1
shift
done
}
cat 'file.yml' | shyaml key-values-0 sites.site1.env |
while readLine key val; do
...
done
However, If I run this in Vagrant (Ubuntu 16.04) I get the following error:
test.sh: 4: read: Illegal option -d
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
I have also tried setting the shebang to: #!/bin/bash and #!/usr/bin/env bash but whenever I ssh into vagrant and $run sh test.sh . I'll get that error.
Ok - so I have changed the way Vagrant runs the provision script by using the inline provisioning and running the script with /bin/bash. So: config.vm.provision :shell, inline: '/bin/bash ' + File.join( 'provision', 'test.sh' )

Perlbrew installation through vagrant provision.sh

I want to automate the installation of perlbrew into the vagrant box. I use .sh file to accomplish this.
provision.sh
apt-get update
sudo -H -u vagrant bash -c " \curl -kL https://install.perlbrew.pl | bash"
sudo -u vagrant bash -c "source ~/perl5/perlbrew/etc/bashrc"
After ssh into the vagrant i expect that
$ which perlbrew
will return
/home/vagrant/perl5/perlbrew/bin/perlbrew
but unfortunately it returns nothing.
There is no way the settings applied by your source ~/perl5/perlbrew/etc/bashrc command would be visible in another bash session (and a SSH session executes a new bash process).
You need to add the command source ~/perl5/perlbrew/etc/bashrc to one of the bash "rc" files.
For a single user with the following command:
echo "source ~/perl5/perlbrew/etc/bashrc" >> ~/.bashrc
For all users with the following command:
echo "source ~/perl5/perlbrew/etc/bashrc" >> /etc/bash.bashrc
This way every time a new bash session is started, it will run source ~/perl5/perlbrew/etc/bashrc and apply the settings.

Resources