You can config your kubectl to talk to EKS both ways
AWSCli Token
pankaj@PGautam-X280:~/terraform/eks3-thar$ aws eks get-token --cluster-name thar-eks-dev-cluster-2
{"kind": "ExecCredential", "apiVersion": "client.authentication.k8s.io/v1alpha1", "spec": {}, "status": {"expirationTimestamp": "2019-11-01T21:59:14Z", "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR
5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZY
Q1MTRaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rO
HMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yNTdmNTE4YjBjOWNjZGE4MmNmOTk1YWI2ND
FmYzZjZTM2YTdhYTZiM2UwNjBmZGUwZDg3ZTMzMWQ1NGYyODQ5"}}
Heptio Token
pankaj@PGautam-X280:~/terraform/eks3-thar$ aws-iam-authenticator token -i eks-thar-techops-dev-cluster-1
{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1alpha1","spec":{},"status":{"token":"k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aX
R5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYL
JlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzL
WlkJlgtQW16LVNpZ25hdHVyZT00M2Q2NmUzNWI4ZWNlNDExNzEwYmMxOTNjNzI4YmEzMGM
wN2E2ZjZjNjRmZDIxN2Y1ZjYwODk0NGNmZmMwM2Zk"}}
AWSCli configuration file:
apiVersion: v1
clusters:
- cluster:
server: https://093E146E63E428CC642F01362F6BE661.sk1.us-west-2.eks.amazonaws.com
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURB
ZtQm1WQ1U4OXZDamZpOXBNaQo2Nmp3NkxTWSttbnFQYzhVcUdVbks5WURhZU01b0ZvULQo=
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: aws
name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws
env:
- name: AWS_PROFILE
value: opssbx
args:
- "eks"
- "get-token"
- "--cluster-name"
- "thar-eks-dev-cluster-2"
# - "--role"
# - "arn:aws:iam::191829356374:role/ops"
Heptio configuration file:
apiVersion: v1
clusters:
- cluster:
server: https://093E146E63E428CC642F01362F6BE661.sk1.us-west-2.eks.amazonaws.com
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURB
TkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHV
npNQjRYRFRFNU1URXdNVEU1TURJMU1Wb1hEVEk1TVRBeU9URTVNREkxTVZvd0ZURVR
NQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQl
GSUNBVEUtLS0tLQo=
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: aws
name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws-iam-authenticator
env:
- name: AWS_PROFILE
value: opssbx
args:
- "token"
- "-i"
- "thar-eks-dev-cluster-2"
Friday, November 1, 2019
Thursday, October 31, 2019
AWS EKS cluster authentication Unauthorized
Scenario: After you created a EKS cluster with worker nodes using Terraform. You are not able to connect to the cluster endpoint. The cluster was created from an account which has admin rights to assume roles in other accounts. We confirmed the authorized roles and policies are correct. This terraform was used multiple times to create a dev cluster, however this time we are creating the cluster in a different account.
It seems like the EKS is not able to validate the user, or we are not able to send the right user/credential to the cluster. So its not an authorization issue but an authentication problem.
So, we have explore more into authentication modules rather then EKS role based access control (RBAC)
One of the first thing you can do is enable cluster auth logs and see which user cloudwatch is capturing as access denied.
error: You must be logged in to the server (the server has asked for the client to provide credentials)
pankaj@PGautam-X280:~/terraform/eks3-thar$ kubectl get nodes
error: the server doesn't have a resource type "nodes"
pankaj@PGautam-X280:~/terraform/eks3-thar$ kubectl version --v=7
I1030 15:55:05.651723 23213 loader.go:359] Config loaded from file /home/pankaj/.kube/config
I1030 15:55:05.653152 23213 round_trippers.go:383] GET https://A4A4CXXX0XXXXXXXE.gr7.us-west-2.eks.amazonaws.com/version?timeout=32s
I1030 15:55:05.653363 23213 round_trippers.go:390] Request Headers:
I1030 15:55:05.653585 23213 round_trippers.go:393] Accept: application/json, */*
I1030 15:55:05.653855 23213 round_trippers.go:393] User-Agent: kubectl/v1.11.2 (linux/amd64) kubernetes/bb9ffb1
I1030 15:55:06.023642 23213 round_trippers.go:408] Response Status: 401 Unauthorized in 369 milliseconds
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-07T23:17:28Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
I1030 15:55:06.035173 23213 helpers.go:201] server response object: [{
"metadata": {},
"status": "Failure",
"message": "the server has asked for the client to provide credentials",
"reason": "Unauthorized",
"details": {
"causes": [
{
"reason": "UnexpectedServerResponse",
"message": "unknown"
}
]
},
"code": 401
}]
F1030 15:55:06.036149 23213 helpers.go:119]
error: You must be logged in to the server (the server has asked for the client to provide credentials)
=========================================
Solution:
Cluster is active
pankaj@PGautam-X280:~/terraform/eks3-thar$ aws eks --profile ops --region us-west-2 describe-cluster --name eks-dev-cluster-1 --query cluster.status
"ACTIVE"
Heptio token works:
pankaj@PGautam-X280:~/terraform/eks3-thar$ aws-iam-authenticator token -i eks-dev-cluster-1
{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1alpha1","spec":{},"status":{"token":"k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZ
W50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNI
QTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFaUkhORE9GVzJPM0ZXUjdIJTJGMjAxOTEw
N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT1jZjk4NTg5MDI2ZjA2MjMyM2Y5Njh
iNDljMzI2YWZmYmI5MDcxNzBlMTUxZDNlN2QxYzA0NGFiOWE0MDcxNTc3"}}
Update .kube config with env:
pankaj@PGautam-X280:~/terraform/eks3-thar$ echo $KUBECONFIG
/home/pankaj/terraform/eks3-thar/config
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws-iam-authenticator
env:
- name: AWS_PROFILE
value: opssbx
args:
- "token"
- "-i"
- "eks-dev-cluster-1"
pankaj@PGautam-X280:~/terraform/eks3-thar$ kubectl version
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-07T23:17:28Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"14+", GitVersion:"v1.14.6-eks-5047ed", GitCommit:"5047edce664593832e9b889e447ac75ab104f527", GitTreeState:"clean", BuildDate:"2019-08-21T22:32:40Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"}
It seems like the EKS is not able to validate the user, or we are not able to send the right user/credential to the cluster. So its not an authorization issue but an authentication problem.
So, we have explore more into authentication modules rather then EKS role based access control (RBAC)
One of the first thing you can do is enable cluster auth logs and see which user cloudwatch is capturing as access denied.
Errors:
pankaj@PGautam-X280:~/terraform/eks3-thar$ kubectl versionClient Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-07T23:17:28Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}error: You must be logged in to the server (the server has asked for the client to provide credentials)
pankaj@PGautam-X280:~/terraform/eks3-thar$ kubectl get nodes
error: the server doesn't have a resource type "nodes"
pankaj@PGautam-X280:~/terraform/eks3-thar$ kubectl version --v=7
I1030 15:55:05.651723 23213 loader.go:359] Config loaded from file /home/pankaj/.kube/config
I1030 15:55:05.653152 23213 round_trippers.go:383] GET https://A4A4CXXX0XXXXXXXE.gr7.us-west-2.eks.amazonaws.com/version?timeout=32s
I1030 15:55:05.653363 23213 round_trippers.go:390] Request Headers:
I1030 15:55:05.653585 23213 round_trippers.go:393] Accept: application/json, */*
I1030 15:55:05.653855 23213 round_trippers.go:393] User-Agent: kubectl/v1.11.2 (linux/amd64) kubernetes/bb9ffb1
I1030 15:55:06.023642 23213 round_trippers.go:408] Response Status: 401 Unauthorized in 369 milliseconds
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-07T23:17:28Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
I1030 15:55:06.035173 23213 helpers.go:201] server response object: [{
"metadata": {},
"status": "Failure",
"message": "the server has asked for the client to provide credentials",
"reason": "Unauthorized",
"details": {
"causes": [
{
"reason": "UnexpectedServerResponse",
"message": "unknown"
}
]
},
"code": 401
}]
F1030 15:55:06.036149 23213 helpers.go:119]
error: You must be logged in to the server (the server has asked for the client to provide credentials)
=========================================
Solution:
Cluster is active
pankaj@PGautam-X280:~/terraform/eks3-thar$ aws eks --profile ops --region us-west-2 describe-cluster --name eks-dev-cluster-1 --query cluster.status
"ACTIVE"
Heptio token works:
pankaj@PGautam-X280:~/terraform/eks3-thar$ aws-iam-authenticator token -i eks-dev-cluster-1
{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1alpha1","spec":{},"status":{"token":"k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZ
W50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNI
QTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFaUkhORE9GVzJPM0ZXUjdIJTJGMjAxOTEw
N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT1jZjk4NTg5MDI2ZjA2MjMyM2Y5Njh
iNDljMzI2YWZmYmI5MDcxNzBlMTUxZDNlN2QxYzA0NGFiOWE0MDcxNTc3"}}
Update .kube config with env:
pankaj@PGautam-X280:~/terraform/eks3-thar$ echo $KUBECONFIG
/home/pankaj/terraform/eks3-thar/config
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws-iam-authenticator
env:
- name: AWS_PROFILE
value: opssbx
args:
- "token"
- "-i"
- "eks-dev-cluster-1"
pankaj@PGautam-X280:~/terraform/eks3-thar$ kubectl version
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-07T23:17:28Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"14+", GitVersion:"v1.14.6-eks-5047ed", GitCommit:"5047edce664593832e9b889e447ac75ab104f527", GitTreeState:"clean", BuildDate:"2019-08-21T22:32:40Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"}
Tuesday, January 15, 2019
AWS EKS - elb in pending state
## ELB Error ( in pending state)
Error creating load balancer (will retry): failed to ensure load balancer for service default/hellopankajgautam:
Solution: Tagging required for VPC/Subnets and private
https://docs.aws.amazon.com/eks/latest/userguide/network_reqs.html
"kubernetes.io/cluster/${var.product}-${var.env}-${var.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
in my experience so far - the only time elb is in pending state -
if there not tagging available as mentioned above
or there is no ips left
or if there is any soft limit errors
Error creating load balancer (will retry): failed to ensure load balancer for service default/hellopankajgautam:
Solution: Tagging required for VPC/Subnets and private
https://docs.aws.amazon.com/eks/latest/userguide/network_reqs.html
"kubernetes.io/cluster/${var.product}-${var.env}-${var.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
in my experience so far - the only time elb is in pending state -
if there not tagging available as mentioned above
or there is no ips left
or if there is any soft limit errors
Thursday, March 23, 2017
cloudformation, cloud-init, cfn-init with redhat 7
I started playing with CloudFormation, Designer a month back and so far it is working out pretty well to all my requirements.
## CloudFormation Designer is pretty nice which allows you can visualize the whole architecture in one frame. It is also very useful and handy if you would like to review just one resource, just select the resource and see code in component tab.
However its kind of painful when the drawing goes haywire and you have to stretch it back to same proportion. Sometime you can cannot select a component directly to drag/move it around. Another problem is with JSON validation. It gives some strange co-ordinates when there is an improper syntax, instead pointing out the line number.
If you are in the same show and looking for a tool to validate JSON,
Please look at http://jsonlint.com/
## It's comparatively very easy to start with CF and deploy a simple infrastructure. For example you can create a VPC, public subnet, private subnet, security groups, Internet gateway, Route table, Network ACLs etc. You can do advance setup like auto scaling, ELB etc also. It may take some time you work with JSON again to figure out EC2 properties like Network interfaces, Network ACL rules, etc. How depends on works?
Some of the cryptic errors are "Device property cannot be empty". Make sure you review the whole template and see what doesn't make sense. Also the "Events" tab while template is running gives you enough clue what's going on. I don't know if there is any way to try out some of these commands without running the entire template.
## Once you have mastered infrastructure code, then comes application provisioning and deployment. And that's where most of the cloud-init and cfn-init mostly comes into play.
When you can start a EC2 you can do few automation with "UserData", but if you have to do a whole bunch of the things at the time of creation, "UserData" becomes nightmare because the way it reads the syntax.
## cloud-init
Cloud-init will execute whatever is defined in "UserData". For example if you want to get object from private S3 and execute a script or copy a config. You can execute everything exposing your AWS Access key and Secret key like we do using CLI in the CF template.
Best practice is to use role for EC2 using Cloudformation Authentication where you only allow the instance to authenticate to the private S3 and download config or execute script using cfn-init.
## cfn-init
For some reason its not very straight forward and documented well if you have to install cfn-init on redhat, as of now atleast.
=====================================================================
"UserData": {
"Fn::Base64": {
"Fn::Join": [ "", [ "#!/bin/bash -ex", "\n",
"cd /root \n",
"yum -y install unzip wget dos2unix git bind-utils ec2-net-utils \n",
"curl https://s3.amazonaws.com/aws-cli/awscli-bundle.zip -o awscli-bundle.zip \n",
"unzip awscli-bundle.zip \n",
"awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws \n",
"python awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws \n",
"curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \n",
"python get-pip.py \n",
"pip install pystache \n",
"pip install argparse \n",
"pip install python-daemon \n",
"pip install requests \n",
"cd /opt \n",
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz -o aws-cfn-bootstrap-latest.tar.gz \n",
"tar -xvpf aws-cfn-bootstrap-latest.tar.gz \n",
"cd aws-cfn-bootstrap*/ \n",
"python setup.py build \n",
"python setup.py install \n",
"cd /opt \n",
"mkdir aws \n",
"cd aws \n",
"mkdir bin \n",
"ln -s /usr/bin/cfn-hup /opt/aws/bin/cfn-hup \n",
"ln -s /usr/bin/cfn-init /opt/aws/bin/cfn-init \n",
"/opt/aws/bin/cfn-init -v ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource upsrcinst1",
" --region ", { "Ref" : "AWS::Region" }, "\n",
"dos2unix /script.sh \n",
"sh /
script
.sh \n", "\n"
] ]
}
},
"Tags": [ { "Key": "Name", "Value": "app-server" } ]
},
Reference:
https://aws.amazon.com/blogs/devops/authenticated-file-downloads-with-cloudformation/
These are the 3 items you have to include in CF script.
1. Create IAM Roles/Policies
Create InstanceRole
Create RolePolicies
Create InstanceProfile
(It will auto create a Role XXXX-InstanceRole-1H2PIS782ZM81)
Under Instance resource:
2. Include in instance metadata:
Create CloudFormation Authentication
Create Cloudformation Init
3. Include IAM Instance profile in instance properties:
"IamInstanceProfile":{ "Ref":"InstanceProfile" },
=====================================================================
"InstanceRole":{
"Type":"AWS::IAM::Role",
"Properties":{
"AssumeRolePolicyDocument":{
"Statement":[ { "Effect":"Allow", "Principal":{ "Service":[ "ec2.amazonaws.com" ] }, "Action":[ "sts:AssumeRole" ] } ]
},
"Path":"/"
}
},
"RolePolicies":{
"Type":"AWS::IAM::Policy",
"Properties":{
"PolicyName":"S3Download",
"PolicyDocument":{
"Statement":[ { "Action":[ "s3:GetObject" ], "Effect":"Allow", "Resource":"arn:aws:s3:::bucket/bucketfolder/*" } ]
},
"Roles":[ { "Ref":"InstanceRole" } ]
}
},
"InstanceProfile":{
"Type":"AWS::IAM::InstanceProfile",
"Properties":{
"Path":"/",
"Roles":[ { "Ref":"InstanceRole" } ]
}
},
====================================================================
"Metadata": {
"AWS::CloudFormation::Designer": { "id": "85a7776e-769f-4f98-85e0-87e7b58f381f" },
"AWS::CloudFormation::Authentication":{ "S3AccessCreds":{ "type":"S3", "roleName":{ "Ref":"InstanceRole" }, "buckets" : ["bucket"] } },
"AWS::CloudFormation::Init": { "config": { "files": { "/root/script.sh": { "source": "https://s3-us-west-2.amazonaws.com/bucket/bucketfolder/script.sh", "mode":"000755", "owner":"ec2-user", "authentication":"S3AccessCreds" } } } }
}
=====================================================================
"inst1": {
"Type": "AWS::EC2::Instance",
"DependsOn": "upsrcebs1",
"Properties": {
"IamInstanceProfile":{ "Ref":"InstanceProfile" },
----
----
}
=====================================================================
## CloudFormation Designer is pretty nice which allows you can visualize the whole architecture in one frame. It is also very useful and handy if you would like to review just one resource, just select the resource and see code in component tab.
However its kind of painful when the drawing goes haywire and you have to stretch it back to same proportion. Sometime you can cannot select a component directly to drag/move it around. Another problem is with JSON validation. It gives some strange co-ordinates when there is an improper syntax, instead pointing out the line number.
If you are in the same show and looking for a tool to validate JSON,
Please look at http://jsonlint.com/
## It's comparatively very easy to start with CF and deploy a simple infrastructure. For example you can create a VPC, public subnet, private subnet, security groups, Internet gateway, Route table, Network ACLs etc. You can do advance setup like auto scaling, ELB etc also. It may take some time you work with JSON again to figure out EC2 properties like Network interfaces, Network ACL rules, etc. How depends on works?
Some of the cryptic errors are "Device property cannot be empty". Make sure you review the whole template and see what doesn't make sense. Also the "Events" tab while template is running gives you enough clue what's going on. I don't know if there is any way to try out some of these commands without running the entire template.
## Once you have mastered infrastructure code, then comes application provisioning and deployment. And that's where most of the cloud-init and cfn-init mostly comes into play.
When you can start a EC2 you can do few automation with "UserData", but if you have to do a whole bunch of the things at the time of creation, "UserData" becomes nightmare because the way it reads the syntax.
## cloud-init
Cloud-init will execute whatever is defined in "UserData". For example if you want to get object from private S3 and execute a script or copy a config. You can execute everything exposing your AWS Access key and Secret key like we do using CLI in the CF template.
Best practice is to use role for EC2 using Cloudformation Authentication where you only allow the instance to authenticate to the private S3 and download config or execute script using cfn-init.
## cfn-init
For some reason its not very straight forward and documented well if you have to install cfn-init on redhat, as of now atleast.
=====================================================================
"UserData": {
"Fn::Base64": {
"Fn::Join": [ "", [ "#!/bin/bash -ex", "\n",
"cd /root \n",
"yum -y install unzip wget dos2unix git bind-utils ec2-net-utils \n",
"curl https://s3.amazonaws.com/aws-cli/awscli-bundle.zip -o awscli-bundle.zip \n",
"unzip awscli-bundle.zip \n",
"awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws \n",
"python awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws \n",
"curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \n",
"python get-pip.py \n",
"pip install pystache \n",
"pip install argparse \n",
"pip install python-daemon \n",
"pip install requests \n",
"cd /opt \n",
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz -o aws-cfn-bootstrap-latest.tar.gz \n",
"tar -xvpf aws-cfn-bootstrap-latest.tar.gz \n",
"cd aws-cfn-bootstrap*/ \n",
"python setup.py build \n",
"python setup.py install \n",
"cd /opt \n",
"mkdir aws \n",
"cd aws \n",
"mkdir bin \n",
"ln -s /usr/bin/cfn-hup /opt/aws/bin/cfn-hup \n",
"ln -s /usr/bin/cfn-init /opt/aws/bin/cfn-init \n",
"/opt/aws/bin/cfn-init -v ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource upsrcinst1",
" --region ", { "Ref" : "AWS::Region" }, "\n",
"dos2unix /script.sh \n",
"sh /
script
.sh \n", "\n"
] ]
}
},
"Tags": [ { "Key": "Name", "Value": "app-server" } ]
},
Reference:
https://aws.amazon.com/blogs/devops/authenticated-file-downloads-with-cloudformation/
These are the 3 items you have to include in CF script.
1. Create IAM Roles/Policies
Create InstanceRole
Create RolePolicies
Create InstanceProfile
(It will auto create a Role XXXX-InstanceRole-1H2PIS782ZM81)
Under Instance resource:
2. Include in instance metadata:
Create CloudFormation Authentication
Create Cloudformation Init
3. Include IAM Instance profile in instance properties:
"IamInstanceProfile":{ "Ref":"InstanceProfile" },
=====================================================================
"InstanceRole":{
"Type":"AWS::IAM::Role",
"Properties":{
"AssumeRolePolicyDocument":{
"Statement":[ { "Effect":"Allow", "Principal":{ "Service":[ "ec2.amazonaws.com" ] }, "Action":[ "sts:AssumeRole" ] } ]
},
"Path":"/"
}
},
"RolePolicies":{
"Type":"AWS::IAM::Policy",
"Properties":{
"PolicyName":"S3Download",
"PolicyDocument":{
"Statement":[ { "Action":[ "s3:GetObject" ], "Effect":"Allow", "Resource":"arn:aws:s3:::bucket/bucketfolder/*" } ]
},
"Roles":[ { "Ref":"InstanceRole" } ]
}
},
"InstanceProfile":{
"Type":"AWS::IAM::InstanceProfile",
"Properties":{
"Path":"/",
"Roles":[ { "Ref":"InstanceRole" } ]
}
},
====================================================================
"Metadata": {
"AWS::CloudFormation::Designer": { "id": "85a7776e-769f-4f98-85e0-87e7b58f381f" },
"AWS::CloudFormation::Authentication":{ "S3AccessCreds":{ "type":"S3", "roleName":{ "Ref":"InstanceRole" }, "buckets" : ["bucket"] } },
"AWS::CloudFormation::Init": { "config": { "files": { "/root/script.sh": { "source": "https://s3-us-west-2.amazonaws.com/bucket/bucketfolder/script.sh", "mode":"000755", "owner":"ec2-user", "authentication":"S3AccessCreds" } } } }
}
=====================================================================
"inst1": {
"Type": "AWS::EC2::Instance",
"DependsOn": "upsrcebs1",
"Properties": {
"IamInstanceProfile":{ "Ref":"InstanceProfile" },
----
----
}
=====================================================================
Subscribe to:
Posts (Atom)
