I am working on a AWS cloudformation template that creates an opsworks stack.
In my stack, I will have one instance (Ubuntu 14.04) , all the applications and packages that will be installed in the instance are configured in the chef cookbook provided from an S3 bucket. I need to set an environment variable in my instance and its value is to be set by a parameter of the cloudformation template, this is the template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AWS CloudFormation Template : Stack OpsWorks Slave pour deployer les instances script",
"Mappings": {
"Region2Principal": {
"us-east-1": {
"EC2Principal": "ec2.amazonaws.com",
"OpsWorksPrincipal": "opsworks.amazonaws.com"
},
"us-west-2": {
"EC2Principal": "ec2.amazonaws.com",
"OpsWorksPrincipal": "opsworks.amazonaws.com"
},
"us-west-1": {
"EC2Principal": "ec2.amazonaws.com",
"OpsWorksPrincipal": "opsworks.amazonaws.com"
},
"eu-west-1": {
"EC2Principal": "ec2.amazonaws.com",
"OpsWorksPrincipal": "opsworks.amazonaws.com"
}
},
"AWSInstanceType2Arch" : {
"t1.micro" : { "Arch" : "PV64" },
"t2.micro" : { "Arch" : "HVM64" },
"m1.small" : { "Arch" : "PV64" },
"m1.large" : { "Arch" : "PV64" },
"m4.large" : { "Arch" : "HVM64" },
"m4.xlarge" : { "Arch" : "HVM64" },
"m4.2xlarge" : { "Arch" : "HVM64" },
"m4.4xlarge" : { "Arch" : "HVM64" },
"m4.10xlarge" : { "Arch" : "HVM64" },
"m4.16xlarge" : { "Arch" : "HVM64" },
"c3.large" : { "Arch" : "HVM64" },
"c3.xlarge" : { "Arch" : "HVM64" },
"c3.2xlarge" : { "Arch" : "HVM64" },
"c3.4xlarge" : { "Arch" : "HVM64" },
"c3.8xlarge" : { "Arch" : "HVM64" },
"c4.large" : { "Arch" : "HVM64" },
"c4.xlarge" : { "Arch" : "HVM64" },
"c4.2xlarge" : { "Arch" : "HVM64" },
"c4.4xlarge" : { "Arch" : "HVM64" },
"c4.8xlarge" : { "Arch" : "HVM64" }
},
"AWSRegionArch2AMI" : {
"us-east-1" : { "PV64" : "ami-5fb8c835", "HVM64" : "ami-60b6c60a" },
"us-west-1" : { "PV64" : "ami-56ea8636", "HVM64" : "ami-d5ea86b5" },
"eu-west-1" : { "PV64" : "ami-95e33ce6", "HVM64" : "ami-bff32ccc" },
"us-west-2" : { "PV64" : "ami-d93622b8", "HVM64" : "ami-f0091d91" }
}
},
"Parameters": {
"OpsWorksStackColor": {
"Description": "RGB Color to use for OpsWorks Stack",
"Type": "String",
"Default": "rgb(38, 146, 168)"
},
"Region" : {
"Type":"String",
"Description": "Region location of the template resources",
"Default": "eu-west-1",
"AllowedValues" : [ "us-east-1", "us-west-1", "us-west-2", "eu-west-1" ]
},
"SecurityGroupIds": {
"Description": "Security groups that can be used to access the EC2 instances, do not select more than 5 SG",
"Type": "List<AWS::EC2::SecurityGroup::Id>",
"ConstraintDescription": "must be list of EC2 security group ids"
},
"VpcId": {
"Type": "AWS::EC2::VPC::Id",
"Description": "VPC associated with the provided subnets",
"Default": "vpc-69e3320c",
"ConstraintDescription": "must be an existing VPC ID"
},
"SubnetId": {
"Type": "String",
"Default": "subnet-6820eb31",
"ConstraintDescription": "must be an existing subnet ID"
},
"InstanceType": {
"Type": "String",
"Default": "c3.large",
"AllowedValues" : ["t2.micro", "m1.small", "m1.large","m4.large","m4.xlarge","m4.2xlarge","m4.4xlarge","m4.10xlarge","m4.16xlarge","c4.large" , "c4.xlarge" ,"c4.2xlarge" , "c4.4xlarge","c4.8xlarge" , "c3.large" , "c3.xlarge", "c3.2xlarge", "c3.4xlarge" ,"c3.8xlarge"],
"ConstraintDescription": "must be a valid EC2 instance type"
},
"KeyPairName": {
"Type": "AWS::EC2::KeyPair::KeyName",
"Default": "test-generic-ec2",
"ConstraintDescription": "must be the name of an existing EC2 KeyPair"
},
"CookbookS3" : {
"Type": "String",
"Default": "https://s3-eu-west-1.amazonaws.com/MybucketJRBLO.cookbooks/cookbook-v2.tar.gz",
"ConstraintDescription": "the Url to the cookbook"
},
"CookbookS3AccessID": {
"Type": "String",
"ConstraintDescription": "username to the appropriate IAM access key ID"
},
"CookbookS3AccessKey": {
"Type": "String",
"NoEcho" : "true",
"ConstraintDescription": "password to the appropriate IAM secret access key"
},
"Environnement" : {
"Description": "The Environnement variable ",
"Type": "String",
"Default": "test",
"AllowedValues" : ["dev", "test", "int", "prod"]
}
},
"Conditions" : {
"CreateProdResources" : { "Fn::Not" : [{ "Fn::Equals" : [ {"Ref" : "Environnement"},"test" ] }] }
},
"Resources": {
"MabStack": {
"Type": "AWS::OpsWorks::Stack",
"Properties": {
"AgentVersion" : "LATEST",
"Name": { "Ref": "AWS::StackName" },
"Attributes": { "Color": { "Ref": "OpsWorksStackColor" } },
"ChefConfiguration": {},
"ConfigurationManager": { "Name": "Chef", "Version": "12" },
"CustomCookbooksSource": {
"Type": "s3",
"Password" : { "Ref": "CookbookS3AccessKey" },
"Username" : { "Ref": "CookbookS3AccessID" },
"Url": { "Ref": "CookbookS3" }
},
"CustomJson": { "awscli": { "profils": {
"default": {"role_arn": { "Fn::GetAtt": [ "OpsWorksInstanceProfile", "Arn" ] } }
}
}
,
"chef_environment": {"Ref" : "Environnement"}
},
"DefaultInstanceProfileArn": { "Fn::GetAtt": [ "OpsWorksInstanceProfile","Arn" ] },
"DefaultOs": "Ubuntu 14.04 LTS",
"DefaultRootDeviceType": "ebs",
"DefaultSshKeyName": { "Ref": "KeyPairName" },
"DefaultSubnetId" : {"Ref" : "SubnetId" },
"ServiceRoleArn": { "Fn::GetAtt": ["OpsWorksServiceRole", "Arn"] },
"UseCustomCookbooks": true,
"UseOpsworksSecurityGroups" : true,
"VpcId" : { "Ref" : "VpcId" }
}
},
"MabLayer": {
"Type": "AWS::OpsWorks::Layer",
"DependsOn" : "OpsWorksServiceRole",
"Properties": {
"AutoAssignElasticIps" : false,
"AutoAssignPublicIps" : true,
"CustomRecipes" : {
"Configure" : ["cassandra-php-driver::configure"],
"Setup" : ["cassandra-php-driver::setup", "security::setup"]
},
"CustomSecurityGroupIds" : { "Ref" : "SecurityGroupIds" },
"EnableAutoHealing" : true,
"InstallUpdatesOnBoot": false,
"LifecycleEventConfiguration": {
"ShutdownEventConfiguration": {
"DelayUntilElbConnectionsDrained": false,
"ExecutionTimeout": 120 }
},
"Name": "script-node",
"Shortname" : "node",
"StackId": { "Ref": "MabStack" },
"Type": "custom",
"UseEbsOptimizedInstances": true,
"VolumeConfigurations": [ {
"Iops": 10000,
"MountPoint": "/dev/sda1",
"NumberOfDisks": 1,
"Size": 20,
"VolumeType": "gp2"
}]
}
},
"OpsWorksServiceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": { "Service": [ { "Fn::FindInMap": [ "Region2Principal",{ "Ref": "AWS::Region" },"OpsWorksPrincipal" ] } ] },
"Action" : [ "sts:AssumeRole" ]
} ]
},
"Path": "/",
"Policies": [ {
"PolicyName": "opsworks-service",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Action": "*",
"Resource": "*"
} ]
}
} ]
}
},
"OpsWorksInstanceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": { "Service" : [ { "Fn::FindInMap": [ "Region2Principal", { "Ref": "AWS::Region" },"EC2Principal" ] } ] },
"Action" : [ "sts:AssumeRole" ]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "aws-opsworks-instance",
"PolicyDocument": {
"Statement": [{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}]
}
}]
}
},
"OpsWorksInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [ { "Ref": "OpsWorksInstanceRole" } ]
}
},
"MabInstance": {
"Type": "AWS::OpsWorks::Instance",
"Properties": {
"Hostname": "Script",
"RootDeviceType": "ebs",
"StackId": {"Ref": "MabStack"},
"LayerIds": [{"Ref": "MabLayer"}],
"InstanceType": {"Ref" : "InstanceType"}
}
},
"MabApp": {
"Type": "AWS::OpsWorks::App",
"Properties": {
"AppSource" : {
"Type" : "git",
"Url" : "git://github.com:soumab/JRLapplication.git",
"Revision" : "develop"
},
"Description": "Dataimport and connectors",
"Name" : "JRL-App",
"Shortname" : "JRL_app",
"StackId" : {"Ref": "MabStack"},
"Type" : "other"
}
},
}
}
I want my instance to have this environment variable :
export $Apps_ENV = "test" / "int" / "prod"
so the value depends on what the user will select. How to set this variable ? Is it possible through CustomJson ? Or directly in the cookbook ? please help. Thank you.
I successfly acheived what I wanted by the following settings:
I added this to CustomJson in my template :
"settings" : { "var" : {
"default": { "Apps_ENV": {"Ref" : "Environnement"} } }
}
And I added a cookbook as following
settings/recipes/defaults.rb :
template '/etc/environment' do
source 'env.erb'
owner 'root'
group 'root'
mode '0755'
end
and settings/templates/default/env.erb:
<% node['settings']['var'].each do |var_name, var_att| %>
<%= sprintf("[%s]", var_name) %>
<% var_att.each do |attr_name, attr_value| %>
<%= sprintf("%s=%s", attr_name, attr_value) %>
<% end
end %>
Related
I am trying to deploy a MySQL Flexible server cluster using ARM Templates and terraform (since terraform doesn't have any resource for mysql_flexible) but it gives me the following "Internal Server Error" without any meaningful information.
Please provide string value for 'version' (? for help): 5.7
{"status":"Failed","error":{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"Conflict","message":"{\r\n "status": "Failed",\r\n "error": {\r\n "code": "ResourceDeploymentFailure",\r\n "message": "The resource operation completed with terminal provisioning state 'Failed'.",\r\n "details": [\r\n {\r\n "code": "InternalServerError",\r\n "message": "An unexpected error occured while processing the request. Tracking ID: 'b8ab3a01-d4f2-40d5-92cf-2c9a239bdac3'"\r\n }\r\n ]\r\n }\r\n}"}]}}
There's not much information when I paste this tracking ID in Azure Activity Log.
Here's my sample template.json file which I am using.
{
"$schema" : "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion" : "1.0.0.0",
"parameters" : {
"administratorLogin" : {
"type" : "String"
},
"administratorLoginPassword" : {
"type" : "SecureString"
},
"availabilityZone" : {
"type" : "String"
},
"location" : {
"type" : "String"
},
"name" : {
"type" : "String"
},
"version" : {
"type" : "String"
}
},
"resources" : [
{
"apiVersion" : "2021-05-01-preview",
"identity" : {
"type" : "SystemAssigned"
},
"location" : "eastus",
"name" : "mysql-abcd-eastus",
"properties" : {
"administratorLogin" : "randomuser",
"administratorLoginPassword" : "randompasswd",
"availabilityZone" : "1",
"backup" : {
"backupRetentionDays" : "7",
"geoRedundantBackup" : "Disabled"
},
"createMode" : "Default",
"highAvailability" : {
"mode" : "Enabled",
"standbyAvailabilityZone" : "2"
},
"network" : {
"delegatedSubnetResourceId" : "myactualsubnetid",
"privateDnsZoneResourceId" : "myactualprivatednszoneid"
},
"version" : "[parameters('version')]"
},
"sku" : {
"name" : "Standard_E4ds_v4",
"tier" : "MemoryOptimized"
},
"type" : "Microsoft.DBforMySQL/flexibleServers"
}
]
}
I tested your code and faced the same issue . So, as a solution you can try with below Code :
provider "azurerm" {
features {}
}
data "azurerm_resource_group" "example" {
name = "yourresourcegroup"
}
resource "azurerm_resource_group_template_deployment" "example" {
name = "acctesttemplate-01"
resource_group_name = data.azurerm_resource_group.example.name
parameters_content = jsonencode({
"administratorLogin"= {
"value"= "sqladmin"
},
"administratorLoginPassword"= {
"value": "password"
},
"location"= {
"value": "eastus"
},
"serverName"= {
"value"= "ansumantestsql1234"
},
"serverEdition"= {
"value"= "GeneralPurpose"
},
"vCores"= {
"value"= 2
},
"storageSizeGB"= {
"value"= 64
},
"haEnabled"= {
"value"= "ZoneRedundant"
},
"availabilityZone"= {
"value"= "1"
},
"standbyAvailabilityZone"= {
"value"= "2"
},
"version"= {
"value"= "5.7"
},
"tags"= {
"value"= {}
},
"firewallRules"= {
"value"= {
"rules"= []
}
},
"backupRetentionDays"= {
"value"= 7
},
"geoRedundantBackup"= {
"value"= "Disabled"
},
"vmName"= {
"value"= "Standard_D2ds_v4"
},
"publicNetworkAccess"= {
"value"= "Enabled"
},
"storageIops"= {
"value": 1000
},
"storageAutogrow"= {
"value"= "Enabled"
},
"vnetData"= {
"value"= {
"virtualNetworkName"= "testVnet",
"subnetName"= "testSubnet",
"virtualNetworkAddressPrefix"= "10.0.0.0/16",
"virtualNetworkResourceGroupName"= "[resourceGroup().name]",
"location"= "eastus2",
"subscriptionId"= "[subscription().subscriptionId]",
"subnetProperties"= {},
"isNewVnet"= false,
"subnetNeedsUpdate"= false,
"Network"= {}
}
},
"infrastructureEncryption"= {
"value"= "Disabled"
}
})
template_content = <<DEPLOY
{
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"administratorLogin": {
"type": "string"
},
"administratorLoginPassword": {
"type": "securestring"
},
"location": {
"type": "string"
},
"serverName": {
"type": "string"
},
"serverEdition": {
"type": "string"
},
"vCores": {
"type": "int",
"defaultValue": 4
},
"storageSizeGB": {
"type": "int"
},
"haEnabled": {
"type": "string",
"defaultValue": "Disabled"
},
"availabilityZone": {
"type": "string"
},
"standbyAvailabilityZone": {
"type": "string"
},
"version": {
"type": "string"
},
"tags": {
"type": "object",
"defaultValue": {}
},
"firewallRules": {
"type": "object",
"defaultValue": {}
},
"backupRetentionDays": {
"type": "int"
},
"geoRedundantBackup": {
"type": "string"
},
"vmName": {
"type": "string",
"defaultValue": "Standard_B1ms"
},
"publicNetworkAccess": {
"type": "string",
"metadata": {
"description": "Value should be either Enabled or Disabled"
}
},
"storageIops": {
"type": "int"
},
"storageAutogrow": {
"type": "string",
"defaultValue": "Enabled"
},
"vnetData": {
"type": "object",
"metadata": {
"description": "Vnet data is an object which contains all parameters pertaining to vnet and subnet"
},
"defaultValue": {
"virtualNetworkName": "testVnet",
"subnetName": "testSubnet",
"virtualNetworkAddressPrefix": "10.0.0.0/16",
"virtualNetworkResourceGroupName": "[resourceGroup().name]",
"location": "westus2",
"subscriptionId": "[subscription().subscriptionId]",
"subnetProperties": {},
"isNewVnet": false,
"subnetNeedsUpdate": false,
"Network": {}
}
},
"infrastructureEncryption": {
"type": "string"
}
},
"variables": {
"api": "2021-05-01-preview",
"firewallRules": "[parameters('firewallRules').rules]"
},
"resources": [
{
"apiVersion": "[variables('api')]",
"location": "[parameters('location')]",
"name": "[parameters('serverName')]",
"properties": {
"version": "[parameters('version')]",
"administratorLogin": "[parameters('administratorLogin')]",
"administratorLoginPassword": "[parameters('administratorLoginPassword')]",
"publicNetworkAccess": "[parameters('publicNetworkAccess')]",
"Network": "[if(empty(parameters('vnetData').Network), json('null'), parameters('vnetData').Network)]",
"Storage": {
"StorageSizeGB": "[parameters('storageSizeGB')]",
"Iops": "[parameters('storageIops')]",
"Autogrow": "[parameters('storageAutogrow')]"
},
"Backup": {
"backupRetentionDays": "[parameters('backupRetentionDays')]",
"geoRedundantBackup": "[parameters('geoRedundantBackup')]"
},
"availabilityZone": "[parameters('availabilityZone')]",
"highAvailability": {
"mode": "[parameters('haEnabled')]",
"standbyAvailabilityZone": "[parameters('standbyAvailabilityZone')]"
},
"dataencryption": {
"infrastructureEncryption": "[parameters('infrastructureEncryption')]"
}
},
"sku": {
"name": "[parameters('vmName')]",
"tier": "[parameters('serverEdition')]",
"capacity": "[parameters('vCores')]"
},
"tags": "[parameters('tags')]",
"type": "Microsoft.DBforMySQL/flexibleServers"
},
{
"condition": "[greater(length(variables('firewallRules')), 0)]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-08-01",
"name": "[concat('firewallRules-', copyIndex())]",
"copy": {
"count": "[if(greater(length(variables('firewallRules')), 0), length(variables('firewallRules')), 1)]",
"mode": "Serial",
"name": "firewallRulesIterator"
}
}
]
}
DEPLOY
deployment_mode = "Incremental"
}
Output:
I am trying to figure out how to autoformat JSON files in the same manner as standard AWS template. If you run a template through the AWS toolkit or online designer, the format is very readable. Everything I've tried in the JSON Editor ends up looking like crap, but I see tons of templates in json format online that look exactly like the amazon format. I've tried using the AWS toolkit, but that only recognizes files named ".template. Is there a different plugin, or custom settings I should be inputing?
Thanks everyone!
Example (JSON):
{
"AWSTemplateFormatVersion" : "2010-09-09", "Parameters" : {
"LogRetentionTime" : {
"Type" : "Number", "Default" : 90, "Description" : "Flow log retention time in days", "AllowedValues" : [ 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653 ]
}
}, "Resources" : {
"VpcFlowLog" : {
"Type" : "Custom::CreateVpcFlowLogs", "Properties" : {
"ServiceToken" : {
"Ref" : "CreateVpcFlowLogLambdaFunction"
}, "Region" : {
"Ref" : "AWS::Region"
}, "VpcId" : {
"Ref" : "Vpc"
}, "LogGroupName" : {
"Ref" : "VpcLogGroup"
}, "DeliverLogsPermissionArn" : {
"Fn::GetAtt" : [ "FlowLogsRole", "Arn" ]
}
}, "DependsOn" : [ ]
}, "FlowLogsRole" : {
"Type" : "AWS::IAM::Role", "Properties" : {
"AssumeRolePolicyDocument" : {
"Version" : "2012-10-17", "Statement" : [ {
"Effect" : "Allow", "Principal" : {
"Service" : "vpc-flow-logs.amazonaws.com"
}, "Action" : "sts:AssumeRole"
} ]
}, "Policies" : [ {
"PolicyName" : "root", "PolicyDocument" : {
"Version" : "2012-10-17", "Statement" : [ {
"Effect" : "Allow", "Action" : [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogGroups", "logs:DescribeLogStreams" ], "Resource" : "arn:aws:logs:*:*:*"
} ]
}
} ]
}
}, "VpcLogGroup" : {
"Type" : "AWS::Logs::LogGroup", "Properties" : {
"RetentionInDays" : {
"Ref" : "LogRetentionTime"
}
}, "DependsOn" : [ ]
}
}, "Outputs" : {
"VpcFlowLog" : {
"Description" : "Flog log id", "Value" : {
"Fn::GetAtt" : [ "VpcFlowLog", "Id" ]
}
}
}
}
Example (AWS):
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"LogRetentionTime": {
"Type": "Number",
"Default": 90,
"Description": "Flow log retention time in days",
"AllowedValues": [1,3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653]
}
},
"Resources": {
"VpcFlowLog": {
"Type": "Custom::CreateVpcFlowLogs",
"Properties": {
"ServiceToken": { "Ref" : "CreateVpcFlowLogLambdaFunction" },
"Region": { "Ref": "AWS::Region" },
"VpcId": {
"Ref": "Vpc"
},
"LogGroupName": {
"Ref": "VpcLogGroup"
},
"DeliverLogsPermissionArn": {"Fn::GetAtt" : ["FlowLogsRole", "Arn"] }
},
"DependsOn": []
},
"FlowLogsRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "vpc-flow-logs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"Policies": [
{
"PolicyName": "root",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
}
]
}
},
"VpcLogGroup": {
"Type": "AWS::Logs::LogGroup",
"Properties": {
"RetentionInDays": { "Ref" : "LogRetentionTime" }
},
"DependsOn": []
}
},
"Outputs": {
"VpcFlowLog": {
"Description": "Flog log id",
"Value": {
"Fn::GetAtt": [
"VpcFlowLog",
"Id"
]
}
}
}
}
Visual Studio formats them perfectly if you drop manually drop a CRLF into the end of the file it bada booms them into the perfect format.
I'm working on a cloudformation template that has many parameters, like the ID of the elastic file system and the DNS of the MountTarget. I want to retreive these parameters from the existing resources, but if they are not already created I want to create them in the template :
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AWS CloudFormation Template : Stack OpsWorks Slave pour deployer les instances script",
"Mappings": {
"Region2Principal": {
"us-east-1": {
"EC2Principal": "ec2.amazonaws.com",
"OpsWorksPrincipal": "opsworks.amazonaws.com"
},
"us-west-2": {
"EC2Principal": "ec2.amazonaws.com",
"OpsWorksPrincipal": "opsworks.amazonaws.com"
},
"us-west-1": {
"EC2Principal": "ec2.amazonaws.com",
"OpsWorksPrincipal": "opsworks.amazonaws.com"
},
"eu-west-1": {
"EC2Principal": "ec2.amazonaws.com",
"OpsWorksPrincipal": "opsworks.amazonaws.com"
}
},
"AWSInstanceType2Arch" : {
"t1.micro" : { "Arch" : "PV64" },
"t2.micro" : { "Arch" : "HVM64" },
"m1.small" : { "Arch" : "PV64" },
"m1.large" : { "Arch" : "PV64" },
"m4.large" : { "Arch" : "HVM64" },
"m4.xlarge" : { "Arch" : "HVM64" },
"m4.2xlarge" : { "Arch" : "HVM64" },
"m4.4xlarge" : { "Arch" : "HVM64" },
"m4.10xlarge" : { "Arch" : "HVM64" },
"m4.16xlarge" : { "Arch" : "HVM64" },
"c3.large" : { "Arch" : "HVM64" },
"c3.xlarge" : { "Arch" : "HVM64" },
"c3.2xlarge" : { "Arch" : "HVM64" },
"c3.4xlarge" : { "Arch" : "HVM64" },
"c3.8xlarge" : { "Arch" : "HVM64" },
"c4.large" : { "Arch" : "HVM64" },
"c4.xlarge" : { "Arch" : "HVM64" },
"c4.2xlarge" : { "Arch" : "HVM64" },
"c4.4xlarge" : { "Arch" : "HVM64" },
"c4.8xlarge" : { "Arch" : "HVM64" }
},
"AWSRegionArch2AMI" : {
"us-east-1" : { "PV64" : "ami-5fb8c835", "HVM64" : "ami-60b6c60a" },
"us-west-1" : { "PV64" : "ami-56ea8636", "HVM64" : "ami-d5ea86b5" },
"eu-west-1" : { "PV64" : "ami-95e33ce6", "HVM64" : "ami-bff32ccc" },
"us-west-2" : { "PV64" : "ami-d93622b8", "HVM64" : "ami-f0091d91" }
}
},
"Parameters": {
"OpsWorksStackColor": {
"Description": "RGB Color to use for OpsWorks Stack",
"Type": "String",
"Default": "rgb(38, 146, 168)"
},
"Region" : {
"Type":"String",
"Description": "Region location of the template resources",
"Default": "eu-west-1",
"AllowedValues" : [ "us-east-1", "us-west-1", "us-west-2", "eu-west-1" ]
},
"SecurityGroupIds": {
"Description": "Security groups that can be used to access the EC2 instances, do not select more than 5 SG",
"Type": "List<AWS::EC2::SecurityGroup::Id>",
"ConstraintDescription": "must be list of EC2 security group ids"
},
"VpcId": {
"Type": "AWS::EC2::VPC::Id",
"Description": "VPC associated with the provided subnets",
"Default": "vpc-69e3320c",
"ConstraintDescription": "must be an existing VPC ID"
},
"SubnetId": {
"Type": "String",
"Default": "subnet-6820eb31",
"ConstraintDescription": "must be an existing subnet ID"
},
"InstanceType": {
"Type": "String",
"Default": "c3.large",
"AllowedValues" : ["t2.micro", "m1.small", "m1.large","m4.large","m4.xlarge","m4.2xlarge","m4.4xlarge","m4.10xlarge","m4.16xlarge","c4.large" , "c4.xlarge" ,"c4.2xlarge" , "c4.4xlarge","c4.8xlarge" , "c3.large" , "c3.xlarge", "c3.2xlarge", "c3.4xlarge" ,"c3.8xlarge"],
"ConstraintDescription": "must be a valid EC2 instance type"
},
"KeyPairName": {
"Type": "AWS::EC2::KeyPair::KeyName",
"Default": "test-generic-ec2",
"ConstraintDescription": "must be the name of an existing EC2 KeyPair"
},
"CookbookS3" : {
"Type": "String",
"Default": "https://s3-eu-west-1.amazonaws.com/mybucket.test.cookbooks/cookbook-v1.tar.gz",
"ConstraintDescription": "the Url to the cookbook"
},
"CookbookS3AccessID": {
"Type": "String",
"ConstraintDescription": "username to the appropriate IAM access key ID"
},
"CookbookS3AccessKey": {
"Type": "String",
"NoEcho" : "true",
"ConstraintDescription": "password to the appropriate IAM secret access key"
},
"MountPoint" : {
"Description" : "The Linux mount point for the EFS volume",
"Type": "String",
"MinLength": "1",
"Default": "efs-file-appli-tmp"
},
"MountPointDNS" : {
"Description" : "Mount target DNS name",
"Type" : "String",
"Default" : "eu-west-1a.fs-c2388dc0b.efs.eu-west-1.amazonaws.com"
},
"FileSystem" : {
"Description" :"The Id of the FileSystem",
"Type": "String",
"Default": "fs-c2388dc0b"
},
"NewRelicLicence" : {
"Description": "The licence key of newrelic",
"Type": "String"
},
"Environnement" : {
"Description": "The Environnement variable ",
"Type": "String",
"Default": "test",
"AllowedValues" : ["dev", "test", "int", "prod"]
}
},
"Conditions" : {
"CreateProdResources" : { "Fn::Not" : [{ "Fn::Equals" : [ {"Ref" : "Environnement"},"test" ] }] }
},
"Resources": {
"MyStack": {
"Type": "AWS::OpsWorks::Stack",
"Properties": {
"AgentVersion" : "LATEST",
"Name": { "Ref": "AWS::StackName" },
"Attributes": { "Color": { "Ref": "OpsWorksStackColor" } },
"ChefConfiguration": {},
"ConfigurationManager": { "Name": "Chef", "Version": "12" },
"CustomCookbooksSource": {
"Type": "s3",
"Password" : { "Ref": "CookbookS3AccessKey" },
"Username" : { "Ref": "CookbookS3AccessID" },
"Url": { "Ref": "CookbookS3" }
},
"CustomJson": {
"mount" : { "mountdir" : {
"default" : { "dirname" : { "Ref" : "MountPoint" } } }
},
"mountadd" : { "mountdns" : {
"default" : { "mdns" : { "Ref" : "MountPointDNS" }}}
}
},
"DefaultInstanceProfileArn": { "Fn::GetAtt": [ "OpsWorksInstanceProfile","Arn" ] },
"DefaultOs": "Ubuntu 14.04 LTS",
"DefaultRootDeviceType": "ebs",
"DefaultSshKeyName": { "Ref": "KeyPairName" },
"DefaultSubnetId" : {"Ref" : "SubnetId" },
"ServiceRoleArn": { "Fn::GetAtt": ["OpsWorksServiceRole", "Arn"] },
"UseCustomCookbooks": true,
"UseOpsworksSecurityGroups" : true,
"VpcId" : { "Ref" : "VpcId" }
}
},
"MyLayer": {
"Type": "AWS::OpsWorks::Layer",
"DependsOn" : "OpsWorksServiceRole",
"Properties": {
"AutoAssignElasticIps" : false,
"AutoAssignPublicIps" : true,
"CustomRecipes" : {
"Setup" : ["cassandra-php-driver::setup","awscli::setup","crontab::setup","prometheus-server::setup","awslogs::setup","newrelic::php_agent","settings::setup"],
"Configure" : ["cassandra-php-driver::configure","security::configure","settings::default"],
"Deploy": ["imports::deploy"]
},
"CustomSecurityGroupIds" : { "Ref" : "SecurityGroupIds" },
"EnableAutoHealing" : true,
"InstallUpdatesOnBoot": false,
"LifecycleEventConfiguration": {
"ShutdownEventConfiguration": {
"DelayUntilElbConnectionsDrained": false,
"ExecutionTimeout": 120 }
},
"Name": "script-node",
"Shortname" : "node",
"StackId": { "Ref": "MyStack" },
"Type": "custom",
"UseEbsOptimizedInstances": true,
"VolumeConfigurations": [ {
"Iops": 10000,
"MountPoint": "/dev/sda1",
"NumberOfDisks": 1,
"Size": 20,
"VolumeType": "gp2"
}]
}
},
"OpsWorksServiceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": { "Service": [ { "Fn::FindInMap": [ "Region2Principal",{ "Ref": "AWS::Region" },"OpsWorksPrincipal" ] } ] },
"Action" : [ "sts:AssumeRole" ]
} ]
},
"Path": "/",
"Policies": [ {
"PolicyName": "opsworks-service",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Action": "*",
"Resource": "*"
} ]
}
} ]
}
},
"OpsWorksInstanceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": { "Service" : [ { "Fn::FindInMap": [ "Region2Principal", { "Ref": "AWS::Region" },"EC2Principal" ] } ] },
"Action" : [ "sts:AssumeRole" ]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "aws-opsworks-instance",
"PolicyDocument": {
"Statement": [{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}]
}
}]
}
},
"OpsWorksInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [ { "Ref": "OpsWorksInstanceRole" } ]
}
},
"MyInstance": {
"Type": "AWS::OpsWorks::Instance",
"Properties": {
"Hostname": "Script",
"RootDeviceType": "ebs",
"StackId": {"Ref": "MyStack"},
"LayerIds": [{"Ref": "MyLayer"}],
"InstanceType": {"Ref" : "InstanceType"}
}
},
"MyApp": {
"Type": "AWS::OpsWorks::App",
"Properties": {
"AppSource" : {
"Type" : "git",
"Url" : "git://github.com:globlW/My-imports.git",
"Revision" : "develop"
},
"Description": "Dataimport and connectors",
"Name" : "app-Imports",
"Shortname" : "app_imports",
"StackId" : {"Ref": "MyStack"},
"Type" : "other"
}
},
"MyFileSystem" : {
"Type" : "AWS::EFS::FileSystem",
"Condition" : "CreateProdResources",
"Properties" : {
"FileSystemTags" : [{
"Key" : "Name",
"Value" : {"Ref" : "MountPoint"}
}]
}
},
"MountTarget": {
"Type": "AWS::EFS::MountTarget",
"Condition" : "CreateProdResources",
"Properties": {
"FileSystemId": { "Ref": "MyFileSystem" },
"SubnetId": { "Ref": "SubnetId" },
"SecurityGroups": [ { "Ref": "SecurityGroupIds" } ]
}
}
}
}
As you see, I use often the { "Ref" : "FileSystem" } , { "Ref" : "MountPointDNS" } and { "Ref" : "MountPoint" }, I specially need them in the CustomJson. The problem is how to link the parameters with the recent created resources and how to name them ? can I give the same name so that I can always get a value to customjson ?
I hope my issue is clear.
Thank you
It is possible to conditionally use an existing resource using Condition Functions. See the Conditionally use an existing resource example in the documentation, which demonstrates the following pattern:
Parameters:
ExistingResource:
Description: An existing resource (optional).
Default: NONE
Type: String
Conditions:
CreateNewResource: !Equals [!Ref ExistingResource, NONE]
Resources:
NewResource:
Condition: CreateNewResource
Type: # Resource type
Properties: # Resource properties
Outputs:
ResourceId:
Description: Reference to either a newly-created or existing resource.
Value: !If [CreateNewResource, !Ref NewResource, !Ref ExistingResource]
I trying to build infrastracture with Cloudformation json template. When I added two Subnets and SubnetRouteTableAssociation in both availability zones that i need. But creating process failing to create Loadbalancers with error:
CREATE_FAILED AWS::ElasticLoadBalancing::LoadBalancer Rest ELB cannot
be attached to multiple subnets in the same AZ.
Here is the Parameters of AZs:
"AZs" : {
"Description" : "The list of AvailabilityZones.",
"Type" : "CommaDelimitedList",
"Default" : "us-east-1a,us-east-1c"
}
Here is Resources of Subnets, SubnetRouteTableAssociation in both availability zones and ElasticLoadBalancing of Rest:
"PublicSubnet1a" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"CidrBlock" : "10.0.0.0/24",
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AZs" }]
},
"Tags" : [
{"Key": "Name", "Value": {"Fn::Join": ["", ["Offering-", {"Ref": "Env"}, {"Ref": "EnvNum"}, "-VPC"]]}},
{"Key" : "Network", "Value" : "Public" }
]
}
},
"PublicSubnet1c" : {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": { "Ref" : "VPC" },
"CidrBlock": "10.0.1.0/24",
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AZs" }]
},
"Tags" : [
{"Key": "Name", "Value": {"Fn::Join": ["", ["Offering-", {"Ref": "Env"}, {"Ref": "EnvNum"}, "-VPC"]]}},
{"Key" : "Network", "Value" : "Public" }
]
}
},
"PublicSubnet1aRouteTableAssociation" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"SubnetId" : { "Ref" : "PublicSubnet1a" },
"RouteTableId" : { "Ref" : "PublicRouteTable" }
}
},
"PublicSubnet1cRouteTableAssociation" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"SubnetId" : { "Ref" : "PublicSubnet1c" },
"RouteTableId" : { "Ref" : "PublicRouteTable" }
}
},
"RestELB" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"DependsOn": "AttachGateway",
"Properties": {
"LoadBalancerName": {"Fn::Join": ["",["Rest-ELB-", {"Ref": "VPC"}]]},
"CrossZone" : "true",
"Subnets": [{ "Ref": "PublicSubnet1a" },{ "Ref": "PublicSubnet1c" }],
"Listeners" : [
{"LoadBalancerPort" : "80", "InstancePort" : "80","Protocol" : "HTTP"},
{"LoadBalancerPort" : "6060", "InstancePort" : "6060","Protocol" : "HTTP"}
],
"HealthCheck" : {
"Target" : "HTTP:80/",
"HealthyThreshold" : "3",
"UnhealthyThreshold" : "5",
"Interval" : "90",
"Timeout" : "60"
}
}
}
What I'm doing wrong?
Thanks!
"PublicSubnet1a" : {
...
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AZs" }] // <---- selects index 1 from AZs list
},
...
"PublicSubnet1c" : {
...
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AZs" }] // <---- selects the same index 1 from AZs list
},
both of your subnets are selecting the same index from AZs list (see "FN::select" statement). Change the select statement for PublicSubnet1a to be
"Fn::Select": ["0", { "Ref": "AZs" }]
Given i have this example template:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Mappings" : {
"RegionMap" : {
"us-west-1" : { "AMI" : "ami-655a0a20" },
...
}
},
"Resources" : {
"Ec2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
...
},
"DependsOn" : "myDB"
},
"myDB" : {
"Type" : "AWS::RDS::DBInstance",
"Properties" : {
...
}
},
"myDB2" : {
"Type" : "AWS::RDS::DBInstance",
"Properties" : {
...
}
}
}
}
Is it possible to specify multiple DependsOn in any way?
Would be great to have somethink like:
"DependsOn" : ["myDB", "myDB2"]
Whats the normal way?
Yes,
The DependsOn attribute can take a single string or list of strings.
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html
Syntax:
"DependsOn" : [ String, ... ]
This answer comes up first in Google, so I will include how to do multiple dependson attributes in YAML, which I found in this answer.
AnotherProductionResource:
Type: AWS::CloudFormation::Stack
Condition: ISProduction
DependsOn:
- AResource
- MyProductionResource
Properties:
[...]
Yes,
"DependsOn" can take multiple strings. I have listed an example below:
"DependsOn": [ "S3BucketAppElbLogs", "ElbLogAppBucketPolicy" ]
{
"Description": "Create a variable number of EC2 instance resources.",
"Parameters": {
"InstanceCount": {
"Description": "Number of EC2 instances (must be between 1 and 5).",
"Type": "Number",
"Default": 1,
"MinValue": 1,
"MaxValue": 5,
"ConstraintDescription": "Must be a number between 1 and 5."
},
"ImageId": {
"Description": "Image ID to launch EC2 instances.",
"Type": "AWS::EC2::Image::Id",
"Default": "ami-31c9924e"
},
"InstanceType": {
"Description": "Instance type to launch EC2 instances.",
"Type": "String",
"Default": "m3.medium",
"AllowedValues": [
"m3.medium",
"m3.large",
"m3.xlarge",
"m3.2xlarge"
]
}
},
"Conditions": {
"Launch1" : {"Fn::Equals" : [{"Ref" : "InstanceCount"}, "1"]},
"Launch2" : {"Fn::Equals" : [{"Ref" : "InstanceCount"}, "2"]}
},
"Resources": {
"Instance2": {
"Condition": "Launch2",
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": {
"Ref": "ImageId"
},
"InstanceType": {
"Ref": "InstanceType"
}
},
"DependsOn": "Instance1"
},
"Instance1": {
"Condition": "Launch1",
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": {
"Ref": "ImageId"
},
"InstanceType": {
"Ref": "InstanceType"
}
}
}
}
}