01 First, create a trust policy for the new IAM role. Make a new policy document called ec2-role-trust-policy.json and paste the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
02 Run create-role command (OSX/Linux/UNIX) to create the new IAM role that will be attached to your EC2 instance and used by your applications to sign AWS API requests:
aws iam create-role
--role-name EC2-Admin-Role
--assume-role-policy-document file://ec2-role-trust-policy.json
03 The command output should return the new IAM role metadata:
{
"Role": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
]
},
"RoleId": "AROAIMVSYYB5CATLQSAFI",
"CreateDate": "2016-06-08T12:04:37.829Z",
"RoleName": "EC2-Admin-Role",
"Path": "/",
"Arn": "arn:aws:iam::123456789012:role/EC2-Admin-Role"
}
}
04 Run attach-role-policy command (OSX/Linux/UNIX) to assign an IAM policy to your newly created role. The AmazonEC2FullAccess AWS managed policy will be used as example to run the attach-role-policy command. This policy provides full access to AWS EC2 services and resources. The command does not produce an output:
aws iam attach-role-policy
--policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
--role-name EC2-Admin-Role
05 Now create a new IAM Instance Profile. An instance profile is basically a container for the IAM role that is attached to the EC2 instance during the launch process. Run create-instance-profile command (OSX/Linux/UNIX) to create the new instance profile:
aws iam create-instance-profile
--region us-east-1
--instance-profile-name EC2-Web-Server-Profile
06 The command output should return the newly created IAM Instance Profile metadata:
{
"InstanceProfile": {
"InstanceProfileId": "AIPAJH7HIPC6KJHJYJWNG",
"Roles": [],
"CreateDate": "2016-06-08T11:49:54.600Z",
"InstanceProfileName": "EC2-Web-Server-Profile",
"Path": "/",
"Arn": "arn:aws:iam::123456789012:instance-profile/
EC2-Web-Server-Profile"
}
}
07 Run add-role-to-instance-profile command (OSX/Linux/UNIX) to integrate the role created at step no. 2 with the IAM Instance Profile created at step no. 5 (the command does not return an output):
aws iam add-role-to-instance-profile
--role-name EC2-Admin-Role
--instance-profile-name EC2-Web-Server-Profile
08 Run describe-instances command (OSX/Linux/UNIX) to list the running EC2 instance metadata. The metadata will be useful later when this instance will be recreated to attach the new IAM Role/Instance Profile:
aws ec2 describe-instances
--region us-east-1
--instance-ids i-05e4a39942208532d
--query 'Reservations[*].Instances[*].[KeyName,InstanceType,SecurityGroups]'
09 The command output should return the running/existing EC2 instance metadata requested:
[
"MyEC2KeyPair",
"m3.large",
[
{
"GroupName": "MyEC2SecurityGroup",
"GroupId": "sg-a942c9d2"
}
]
]
10 Now that the IAM role is ready for use and you have the running EC2 instance required metadata, run create-image command (OSX/Linux/UNIX) to create an image from your existing EC2 instance. Include the –no-reboot command parameter to guarantee the file system integrity for your new AMI:
aws ec2 create-image
--region us-east-1
--instance-id 07a2ad8872fb3226b
--name "EC2 instance AMI without IAM roles attached"
--description "Web App Stack AMI ver. 2.5"
--no-reboot
11 The command output should return the new Amazon Machine Image (AMI) ID:
{
"ImageId": "ami-b04eg4e5"
}
12 Run run-instances command (OSX/Linux/UNIX) to launch the EC2 instance from the image created at the previous step. The following command example (re)creates an EC2 instance (m3.large) using an AMI with the ID ami-b04eg4e5, the IAM Instance Profile that contains the new IAM role and the rest of the old running EC2 instance configuration attributes:
aws ec2 run-instances
--region us-east-1
--iam-instance-profile Name=EC2-Web-Server-Profile
--image-id ami-b04eg4e5
--count 1
--instance-type m3.large
--key-name MyEC2KeyPair
--security-groups MyEC2SecurityGroup
13 The command output should return the new EC2 instance configuration metadata (including the IAM Instance Profile metadata - highlighted):
{
{
"OwnerId": "567392585563",
"ReservationId": "r-03ef4a3ce591f58ac",
"Groups": [],
"Instances": [
...
"Architecture": "x86_64",
"RootDeviceType": "ebs",
"IamInstanceProfile": {
"Id": "AIPAJABYIFVH3EOJQNPUC",
"Arn": "arn:aws:iam::123456789012:
instance-profile/EC2-Admin-Role"
},
"RootDeviceName": "/dev/xvda",
"VirtualizationType": "hvm",
...
"AmiLaunchIndex": 0
}
]
}
]
}
14 Now transfer the Elastic IP from the old EC2 instance to the new EC2 instance in order to reference the new one. To transfer the Elastic IP, perform the following commands:
- Run disassociate-address command (OSX/Linux/UNIX) to detach the Elastic IP (EIP) address from the old EC2 instance:
aws ec2 disassociate-address
--association-id eipassoc-70dfe9fd5
- Run associate-address command (OSX/Linux/UNIX) to associate the EIP address detached at the previous step with the new EC2 instance:
aws ec2 associate-address
--instance-id i-05e4a39942208532d
--allocation-id eipalloc-70dfe9fd5
15 Once you have verified that your new EC2 instance is working 100%, you should terminate the EC2 old instance to stop incurring charges for the resource. To terminate the EC2 old instance run terminate-instances command (OSX/Linux/UNIX) using the instance ID as identifier:
aws ec2 terminate-instances
--instance-ids i-05e4a39942208532d
16 The command output should return the shutdown request metadata:
{
"TerminatingInstances": [
{
"InstanceId": "i-05e4a39942208532d",
"CurrentState": {
"Code": 32,
"Name": "shutting-down"
},
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}